40 votes

Créer de petits exécutables Haskell ?

Existe-t-il de bons moyens de créer de petits exécutables Haskell ? Avec ghc6, un simple programme Hello World semble atteindre environ 370 Ko (523 Ko avant dépouillement). Hello world en C fait environ 4kB (9kB avant dépouillement).

0 votes

Utilisez la liaison dynamique, comme décrit ici, stackoverflow.com/questions/6115459/

45voto

Caleb Case Points 501

Avec la branche de développement de GHC (quelqu'un sait exactement dans quelle version cela a été ajouté ?):

$ ghc -o hello hello.hs
$ strip -p --strip-unneeded --remove-section=.comment -o hello-small hello
$ du hello hello-small
700 hello
476 hello-small

Ajouter le drapeau -dynamique pour une RTS liée dynamiquement :

$ ghc -dynamic -o hello hello.hs
$ strip -p --strip-unneeded --remove-section=.comment -o hello-small hello
$ du hello hello-small
24  hello
16  hello-small

Voir aussi : http://hackage.haskell.org/trac/ghc/wiki/SharedLibraries/PlatformSupport

Pour la comparaison avec C :

$ gcc hello.c -o hello
$ strip -p --strip-unneeded --remove-section=.comment -o hello-small hello
$ du hello hello-small
12  hello
8   hello-small

0 votes

Si vous obtenez l'erreur "Perhaps you haven't installed the profiling libraries for package `base'", alors apt-get install ghc-dynamic .

0 votes

@ErikAllik Vous avez besoin des outils de ligne de commande. Vous pouvez également essayer d'installer le binutils du paquet homebrew.

21voto

ADEpt Points 4405

GHC lie tout de manière statique (sauf les bibliothèques utilisées par le runtime lui-même, qui sont liées dynamiquement).

Dans le passé, GHC liait toute la bibliothèque (haskell) dès que vous utilisiez quelque chose de celle-ci. Il y a quelques temps, GHC a commencé à lier "par fichier obj", ce qui réduit considérablement la taille du binaire. A en juger par la taille, vous deviez déjà utiliser le nouveau GHC.

D'un autre côté, vous avez déjà beaucoup de choses dans ces 500K, comme un noyau multithread, un garbage collector, etc.

Ajoutez au moins un ramasseur d'ordures à votre code C, puis comparez-les à nouveau :)

1 votes

S'il est vrai que le binaire Haskell contient beaucoup de choses que le binaire C ne contient pas, il est inutile de l'avoir s'il n'est pas utilisé...

5 votes

@liw.fi Si la taille de vos exécutables vous préoccupe tant que ça, le C est le seul langage qui vous convienne.

2 votes

@liw.fi Haskell est presque par définition une affaire de garbage collection, d'exécution multicore, etc. Donc, en fait, il est inutile pas d'avoir tous ces trucs dans le noyau. Ou de ne pas le faire (ce qui entraînerait des efforts supplémentaires dans un noyau modulaire qui pourrait le faire). Et pour quoi faire ? Pour économiser 100K de taille binaire ?

16voto

Don Stewart Points 94361

La taille que vous voyez est le runtime Haskell (libHSrts.a), qui est lié statiquement à chaque exécutable Haskell. S'il s'agissait d'un objet partagé, comme librt.o pour le C, votre binaire ne ferait que quelques k (la taille d'un fichier .o divisé dans la source de la bibliothèque).

À défaut d'implémenter la liaison dynamique de libHSrts.a sur votre plate-forme, vous pouvez réduire la taille de vos exécutables par strip.

9voto

dqd Points 563

Si la taille de votre binaire est vraiment importante, vous pouvez utiliser l'outil gzexe qui empaquette un exécutable (de préférence déjà dépouillé) avec la compression gzip. Sur ma machine Linux 64 bits, l'original bonjour le monde prend 552 KB, après stripping 393 KB, et après stripping et gzipping 125 KB. Le côté sombre du gzipping se situe au niveau des performances : l'exécutable doit d'abord être décompressé.

2 votes

Je ne connaissais pas ça ! C'est une astuce très utile, j'avais un exécutable de 15 Mo qui n'en faisait plus que 7,3 Mo après l'installation. strip mais ensuite à 1,5 MB après gzexe ! J'ai trouvé un autre outil upx qui est utilisé à la place de gzexe a ramené l'exécutable à 1,2 Mo.

8voto

simon Points 5346

Vous devriez compter vos bénédictions (370Kb ? Luuuxury) :

bash$ sbcl
This is SBCL 1.0.24, an implementation of ANSI Common Lisp.

\* (sb-ext:save-lisp-and-die "my.core")
\[undoing binding stack and other enclosing state... done\]
\[saving current Lisp image into ./my.core:
...
done\]
bash$ du -sh my.core 
 25M    my.core
bash$ 

Sérieusement, bien que vous puissiez probablement secouer un peu les binaires d'Haskell, ce n'est pas une comparaison juste avec le C. Il y a beaucoup plus que cela.

La dernière fois que j'ai joué avec ghc (et cela peut être dépassé), tout était lié de manière statique, ce qui sera un facteur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X