Selbst trivial kleine Haskell-Programme werden zu gigantischen ausführbaren Dateien.
Ich habe ein kleines Programm geschrieben, das (mit GHC) in die Binärdatei mit einer Größe von 7 MB kompiliert wurde!
Was kann dazu führen, dass selbst ein kleines Haskell-Programm in die große Binärdatei kompiliert wird?
Was kann ich tun, um dies zu reduzieren?
strip
auf der Binärdatei aus, um die Symboltabelle zu entfernen.strip test
. Dieser Befehl entfernt einige Debug-Informationen aus dem Programm und verkleinert es.data M3 = M3 !V3 !V3 !V3
unddata V3 = V3 !Float !Float !Float
. Kompilieren mitghc -O2 -funbox-strict-fields
.Antworten:
Mal sehen, was los ist, versuchen Sie es
Sie sehen aus der
ldd
Ausgabe, dass GHC eine dynamisch verknüpfte ausführbare Datei erstellt hat, aber nur die C-Bibliotheken dynamisch verknüpft sind ! Alle Haskell-Bibliotheken werden wörtlich kopiert.Nebenbei: Da dies eine grafikintensive App ist, würde ich definitiv mit kompilieren
ghc -O2
Sie können zwei Dinge tun.
Symbole entfernen
Eine einfache Lösung: Entfernen Sie die Binärdatei:
Strip verwirft Symbole aus der Objektdatei. Sie werden in der Regel nur zum Debuggen benötigt.
Dynamisch verknüpfte Haskell-Bibliotheken
In jüngerer Zeit hat GHC Unterstützung für die dynamische Verknüpfung von C- und Haskell-Bibliotheken erhalten . Die meisten Distributionen vertreiben jetzt eine Version von GHC, die die dynamische Verknüpfung von Haskell-Bibliotheken unterstützt. Freigegebene Haskell-Bibliotheken können von vielen Haskell-Programmen gemeinsam genutzt werden, ohne sie jedes Mal in die ausführbare Datei zu kopieren.
Zum Zeitpunkt des Schreibens werden Linux und Windows unterstützt.
Damit die Haskell-Bibliotheken dynamisch verknüpft werden können, müssen Sie sie
-dynamic
wie folgt kompilieren :Außerdem sollten alle Bibliotheken, die Sie freigeben möchten, erstellt werden mit
--enabled-shared
:Am Ende erhalten Sie eine viel kleinere ausführbare Datei, deren C- und Haskell-Abhängigkeiten dynamisch aufgelöst werden.
Und voilà!
was Sie abstreifen können, um noch kleiner zu machen:
Eine eensy weensy ausführbare Datei, die aus vielen dynamisch verknüpften C- und Haskell-Stücken aufgebaut ist:
Ein letzter Punkt: Selbst auf Systemen mit nur statischer Verknüpfung können Sie -split-objs verwenden , um eine .o-Datei pro Funktion der obersten Ebene abzurufen , wodurch die Größe statisch verknüpfter Bibliotheken weiter reduziert werden kann. Es muss GHC mit -split-objs erstellt werden, was einige Systeme vergessen haben.
quelle
cabal install
die installierte Binärdatei nicht standardmäßig?enable-shared
in Betracht gezogen wurde. launchpad.net/ubuntu/+source/pandoc/+bugsHaskell verwendet standardmäßig statische Verknüpfungen. Dies bedeutet, dass die gesamten Bindungen an OpenGL in Ihr Programm kopiert werden. Da sie ziemlich groß sind, wird Ihr Programm unnötig aufgeblasen. Sie können dies umgehen, indem Sie eine dynamische Verknüpfung verwenden, die jedoch standardmäßig nicht aktiviert ist.
quelle
--enabled-shared
". Wenn Ihre Haskell-Plattform also Bibliotheken enthält, die erstellt wurden, ohne dass--enabled shared
Sie die Basisbibliotheken neu kompilieren müssen, was sehr schmerzhaft sein kann.