web-dev-qa-db-fra.com

Pourquoi le GHC est-il si grand / gros?

Y a-t-il une réponse simple: pourquoi le GHC est-il si gros?

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

Pas intéressé par l'évangélisation de "Pourquoi je ne devrais pas me soucier de la taille si Haskell est le bon outil"; c'est une question technique.

145
Christopher Done

C'est vraiment un peu idiot. Chaque bibliothèque fournie avec GHC est fournie en pas moins de 4 versions:

  • statique
  • dynamique
  • profilé
  • GHCi

La version GHCi est juste la version statique liée ensemble dans un seul fichier .o. Les trois autres versions ont également leur propre ensemble de fichiers d'interface (fichiers .hi). Les versions profilées semblent être environ le double de la taille des versions non profilées (ce qui est un peu suspect, je devrais chercher pourquoi).

N'oubliez pas que GHC lui-même est une bibliothèque, vous obtenez donc 4 copies de GHC. Non seulement cela, mais le binaire GHC lui-même est lié statiquement, donc c'est 5 copies de GHC.

Nous avons récemment fait en sorte que GHCi puisse utiliser les fichiers statiques .a. Cela nous permettra de nous débarrasser d'une de ces saveurs. À plus long terme, nous devrions lier dynamiquement GHC, mais c'est un changement plus important car cela impliquerait de faire de la liaison dynamique la valeur par défaut - contrairement à C, avec GHC, vous devez décider à l'avance si vous allez lier dynamiquement ou non. Et nous avons besoin de plus de changements (par exemple pour Cabal et le système de package, entre autres) avant que cela ne soit vraiment pratique.

183
Simon Marlow

Nous devrions probablement comparer les pommes aux pommes et les oranges aux oranges. JRE est un runtime, pas un kit de développement. On peut comparer: la taille source du kit de développement, la taille du kit de développement compilé et la taille compilée du runtime minimal.

Le bundle source OpenJDK 7 est de 82 Mo (download.Java.net/openjdk/jdk7) par rapport au bundle source GHC 7, qui est de 23 Mo (haskell.org/ghc/download_ghc_7_0_1). GHC n'est pas grand ici. Taille d'exécution: openjdk-6-jre-headless sur Ubuntu est de 77 Mo non compressé par rapport à Haskell helloworld, lié statiquement à son temps d'exécution, qui est <1 Mo. GHC n'est pas grand ici.

Là où GHC est grand, c'est la taille du kit de développement compilé:

GHC disk usage

GHC lui-même prend 270 Mo, et avec toutes les bibliothèques et utilitaires qui se réunissent, il prend plus de 500 Mo. Et oui, c'est beaucoup, même avec des bibliothèques de base et un outil de construction/gestionnaire de dépendances. Java est plus petite.

GHC:

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

contre OpenJDK avec des dépendances:

$ 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

Mais c'est encore plus de 100 Mo, pas 26 Mo au moment où vous écrivez.

Les choses lourdes dans ghc6 et ghc6-prof sont:

$ 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

Veuillez noter la taille de libHSghc-6.12.1_p.a. La réponse semble donc être des versions statiques de liaison et de profilage pour chaque bibliothèque.

55
sastanin

Ma conjecture - beaucoup, beaucoup de liens statiques. Chaque bibliothèque doit lier statiquement ses dépendances, qui à leur tour doivent lier statiquement les leurs et les soforth. Et tout cela est souvent compilé avec et sans profilage, et même sans profilage, les binaires ne sont pas supprimés et contiennent donc beaucoup d'informations de débogueur.

9
sclv

Parce qu'il regroupe gcc et un tas de bibliothèques, toutes liées statiquement.

Au moins sous Windows.

8
Marko

La réponse courte est que c'est parce que tous les exécutables sont liés statiquement, peuvent contenir des informations de débogage et que les bibliothèques sont incluses en plusieurs copies. Cela a déjà été dit par d'autres commentateurs.

La liaison dynamique est possible et réduira considérablement la taille. Voici un exemple Hello.hs:

main = putStrLn "Hello world"

Je construis avec GHC 7.4.2 sur Windows.

ghc --make -O2 donne Hello.exe de 1105Ks

Exécuter strip dessus laisse 630 Ko

ghc --make -O2 -dynamic donne 40K

Le dénuder ne laisse que 13K.

Ses dépendances sont de 5 DLL avec une taille totale de 9,2 Mo non supprimés et 5,7 Mo supprimés.

5
nponeccop

Voici la répartition de la taille du répertoire sur ma boîte:

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

Il semble que le plus grand répertoire (123 Mo) soit les binaires pour compiler le compilateur lui-même. Les documents pèsent à un incroyable 65 Mo. La troisième place est Cabal avec 41 Mo.

Le répertoire bin est de 33 Mo, et je pense que seul un sous-ensemble de ce qui est techniquement requis pour construire des applications Haskell.

4
Jacob