Warum ist GHC so groß / groß?

147

Gibt es eine einfache Antwort: Warum ist GHC so groß?

  • OCaml: 2 MB
  • Python: 15 MB
  • SBCL: 9 MB
  • OpenJRE - 26 MB
  • GHC: 113 MB

Nicht interessiert an der Evangelisation von "Warum sollte mir die Größe egal sein, wenn Haskell das richtige Werkzeug ist"; Dies ist eine technische Frage.

Christopher Done
quelle
1
Woher bekommen Sie diese 500 MB? Mein GHC ist bei weitem nicht so groß.
Jacob
Wenn Sie nicht alle Bibliotheken zählen, denke ich ...
Jacob
Entschuldigung, ich habe einen Paketmanager-Download gestartet, der einige Deps enthält. Ich habe es aktualisiert, um die Downloadgröße von der Website widerzuspiegeln. Ich habe eine Bearbeitungszusammenfassung hinzugefügt, die hier jedoch (noch?) Nicht angezeigt wurde. Ich denke, die Frage steht noch. Es ist groß.
Christopher Done
20
Wahrscheinlich sollten wir Äpfel mit Äpfeln und Orangen mit Orangen vergleichen. JRE ist eine Laufzeit, kein Entwickler-Kit. OpenJDK 7- Quellpaket , 82 MB ( download.java.net/openjdk/jdk7 ) vs GHC 7- Quellpaket , 23 MB ( haskell.org/ghc/download_ghc_7_0_1 ). Jetzt Laufzeit: openjdk-6-jre-headless unter Ubuntu, 77 MB unkomprimiert gegen Haskell helloworld, statisch verknüpft mit seiner Laufzeit, <1 MB.
Sastanin
Heute war ich neugierig auf die Größen jetzt 2014. Es scheint, dass das Argument immer noch gilt. Ich habe URLs gefunden: 1.GHC haskell.org/ghc/download_ghc_7_8_3 ; 2.OpenJCK packages.ubuntu.com/precise/openjdk-7-jdk
AnneTheAgile

Antworten:

187

Es ist wirklich ein bisschen albern. Jede mit GHC gelieferte Bibliothek wird in nicht weniger als 4 Varianten angeboten :

  • statisch
  • dynamisch
  • profiliert
  • GHCi

Die GHCi-Version ist nur die statische Version, die in einer einzigen .oDatei miteinander verknüpft ist . Die anderen drei Versionen haben alle ihre eigenen Schnittstellendateien ( .hiDateien). Die profilierten Versionen scheinen ungefähr doppelt so groß zu sein wie die unprofilierten Versionen (was ein bisschen verdächtig ist, ich sollte untersuchen, warum das so ist).

Denken Sie daran, dass GHC selbst eine Bibliothek ist , sodass Sie 4 Kopien von GHC erhalten. Darüber hinaus ist die GHC-Binärdatei selbst statisch verknüpft, das sind also 5 Kopien von GHC.

Wir haben es kürzlich so gemacht, dass GHCi die statischen .aDateien verwenden kann. Dadurch können wir einen dieser Geschmacksrichtungen loswerden. Längerfristig sollten wir GHC dynamisch verknüpfen, aber das ist eine größere Änderung, da dies bedeuten würde, dass die dynamische Verknüpfung zum Standard wird - anders als in C müssen Sie bei GHC im Voraus entscheiden, ob Sie dynamisch verknüpfen möchten oder nicht. Und wir brauchen weitere Änderungen (z. B. an Cabal und dem Paketsystem unter anderem), bevor dies wirklich praktisch ist.

Simon Marlow
quelle
16
Und hier dachte ich, es sei die ganze Logik, die Haskell bietet: faule Auswertung, Typinferenz usw.
mcandre
4
Also, 113 MB / 4 ~ = 28 MB, immer noch größer als OpenJRE ... Aber wenn man bedenkt, dass GHC mit OpenJDK vergleichbar ist, nicht nur mit JRE, fühle ich mich besser.
Earth Engine
1
Nun, da ich denke, dass GHC dynamische Verknüpfungen verwendet, sind Dr. @ Simon Marlows Ideen zur Komprimierung der vier Geschmacksrichtungen vielleicht praktischer? Zitiert: 1. # 3658 (GHCi dynamisch verknüpfen (und Systemlinker verwenden) auf Plattformen, die dies unterstützen) - GHC ghc.haskell.org/trac/ghc/ticket/3658 ; 2. # 8266 (Dynamische Verknüpfung auf Mac) - GHC ghc.haskell.org/trac/ghc/ticket/8266 ; 3. # 8376 (Static Executable + GHC API (+ Dynamic Linking?) Gibt Segfault) - GHC
AnneTheAgile
56

Wahrscheinlich sollten wir Äpfel mit Äpfeln und Orangen mit Orangen vergleichen. JRE ist eine Laufzeit, kein Entwickler-Kit. Wir können vergleichen: Quellgröße des Entwicklungskits, Größe des kompilierten Entwicklungskits und kompilierte Größe der minimalen Laufzeit.

Das OpenJDK 7-Quellpaket umfasst 82 MB (download.java.net/openjdk/jdk7) und das GHC 7-Quellpaket 23 MB (haskell.org/ghc/download_ghc_7_0_1). GHC ist hier nicht groß. Laufzeitgröße: openjdk-6-jre-headless unter Ubuntu ist 77 MB unkomprimiert gegenüber Haskell helloworld, statisch verknüpft mit seiner Laufzeit, die <1 MB ist. GHC ist hier nicht groß.

Wo GHC groß ist, ist die Größe des kompilierten Entwicklungskits:

Verwendung der GHC-Festplatte

GHC selbst benötigt 270 MB und mit allen Bibliotheken und Dienstprogrammen, die zusammenkommen, mehr als 500 MB. Und ja, es ist viel, selbst mit Basisbibliotheken und einem Build-Tool / Abhängigkeitsmanager. Die Java-Entwicklungsplattform ist kleiner.

GHC:

$ aptitude show ghc6 | grep Size
Uncompressed Size: 388M

gegen OpenJDK mit Abhängigkeiten:

$ aptitude show openjdk-6-jdk openjdk-6-jre openjdk-6-jre-headless ant maven2 ivy | grep Size
Uncompressed Size: 34.9M
Uncompressed Size: 905k
Uncompressed Size: 77.3M
Uncompressed Size: 1,585k
Uncompressed Size: 3,736k
Uncompressed Size: 991k

Aber es sind immer noch mehr als 100 MB, nicht 26 MB, während Sie schreiben.

Schwergewichtige Dinge in ghc6 und ghc6-prof sind:

$ dpkg -L ghc6 | grep '\.a$' | xargs ls -1ks | sort -k 1 -n -r | head -3
57048 /usr/lib/ghc-6.12.1/ghc-6.12.1/libHSghc-6.12.1.a
22668 /usr/lib/ghc-6.12.1/Cabal-1.8.0.2/libHSCabal-1.8.0.2.a
21468 /usr/lib/ghc-6.12.1/base-4.2.0.0/libHSbase-4.2.0.0.a
$ dpkg -L ghc6-prof | grep '\.a$' | xargs ls -1ks | sort -k 1 -n -r | head -3
112596 /usr/lib/ghc-6.12.1/ghc-6.12.1/libHSghc-6.12.1_p.a
 33536 /usr/lib/ghc-6.12.1/Cabal-1.8.0.2/libHSCabal-1.8.0.2_p.a
 31724 /usr/lib/ghc-6.12.1/base-4.2.0.0/libHSbase-4.2.0.0_p.a

Bitte beachten Sie, wie groß ist libHSghc-6.12.1_p.a. Die Antwort scheint also statische Verknüpfungs- und Profilversionen für jede Bibliothek da draußen zu sein.

Sastanin
quelle
9

Meine Vermutung - viele, viele statische Verknüpfungen. Jede Bibliothek muss ihre Abhängigkeiten statisch verknüpfen, die wiederum ihre Abhängigkeiten statisch verknüpfen müssen. Und dies alles wird oft sowohl mit als auch ohne Profilerstellung kompiliert, und selbst ohne Profilerstellung werden die Binärdateien nicht entfernt und enthalten daher viele Debugger-Informationen.

sclv
quelle
2
Es würde mir wahrscheinlich nichts ausmachen, wenn GHC zu einem ganzen Programm wechseln und fast alles Modell neu kompilieren würde, ähnlich wie bei jhc. Es könnte sogar schneller kompiliert werden, wenn es verhindern würde, dass 'ld' ausgetauscht wird.
John L
8

Weil es gcc und eine Reihe von Bibliotheken bündelt , die alle statisch verknüpft sind.

Zumindest unter Windows.

Marko
quelle
12
Nein, nicht unter Linux. es kommt nur auf gcc an. da windows kein gcc in seiner "Distribution" hat, muss es mit ghc kommen.
Comonad
5

Hier ist die Aufschlüsselung der Verzeichnisgröße auf meiner Box:

https://spreadsheets.google.com/ccc?key=0AveoXImmNnZ6dDlQeHY2MmxPcEYzYkpweEtDSS1fUlE&hl=de

Es sieht so aus, als ob das größte Verzeichnis (123 MB) die Binärdateien zum Kompilieren des Compilers selbst sind. Die Dokumente wiegen erstaunliche 65 MB. Der dritte Platz ist Cabal mit 41 MB.

Das bin-Verzeichnis ist 33 MB groß, und ich denke, dass nur eine Teilmenge davon technisch erforderlich ist, um Haskell-Anwendungen zu erstellen.

Jacob
quelle
6
Lassen Sie mich noch etwas hinzufügen: Wenn Sie nur den Barebone-Compiler verwenden und alles entfernen, was nicht unbedingt benötigt wird (z. B. das Erstellen eines Profils ohne Profil, das Entfernen usw.), können Sie auf etwa 5 MB reduzieren. Versuchen Sie jedoch, die Compilergröße mit GCC zu vergleichen. (Bearbeitet den Kommentar, also musste ich ihn löschen ... sorry)
fuz
5

Die kurze Antwort lautet, dass alle ausführbaren Dateien statisch verknüpft sind, möglicherweise Debug-Informationen enthalten und Bibliotheken in mehreren Kopien enthalten sind. Dies wurde bereits von anderen Kommentatoren gesagt.

Dynamische Verknüpfungen sind möglich und reduzieren die Größe erheblich. Hier ist ein Beispiel Hello.hs:

main = putStrLn "Hello world"

Ich baue mit GHC 7.4.2 unter Windows.

ghc --make -O2gibt Hello.exevon 1105Ks

Laufen stripauf sie verlässt 630K

ghc --make -O2 -dynamic gibt 40K

Das Abziehen lässt nur 13K.

Die Abhängigkeiten sind 5 DLLs mit einer Gesamtgröße von 9,2 MB (nicht entfernt) und 5,7 MB (nicht entfernt).

nponeccop
quelle