2009-03-31 20 views
39

Esistono buoni modi per creare piccoli eseguibili haskell? Con ghc6 un semplice programma mondiale Hello sembra arrivare a circa 370kB (523kB prima della striscia). Ciao mondo in C è di circa 4kB (9kB prima della striscia).Creazione di piccoli eseguibili haskell?

+0

Utilizzare il collegamento dinamico, come descritto qui, http: // stackoverflow.it/questions/6115459/small-haskell-program-compiled-with-ghc-in-huge-binary –

risposta

44

Con il ramo di sviluppo di GHC (Qualcuno sa esattamente quale versione questo è stato aggiunto?):

$ 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 

aggiungere il flag -Dynamic per un RTS collegati dinamicamente:

$ 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 

Vedi anche : http://hackage.haskell.org/trac/ghc/wiki/SharedLibraries/PlatformSupport

Per fare un confronto con la 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

Funziona per me in ghc 6.12.1. – Joe

+0

Se ottieni "Forse non hai installato le librerie di profilatura per il pacchetto' base '", allora apt-get install ghc-dynamic. – matcheek

+0

quale sarebbe l'equivalente del comando 'strip' su OS X? –

8

Si dovrebbe contare le tue benedizioni (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$ 

Seriamente, però, mentre probabilmente si può scuotere Haskell i binari un po ', in realtà non è un confronto equo con C. C'è un altro succedendo lì .

L'ultima volta che ho giocato con ghc (e questo potrebbe non essere aggiornato) collegava staticamente tutto, il che sarebbe un fattore.

21

GHC collega staticamente tutto (tranne le librerie utilizzate dal runtime stesso, che sono collegate dinamicamente).

Nella vecchia era, GHC ha collegato l'intera libreria (haskell) non appena ne hai usato qualcosa. Qualche tempo fa, GHC ha iniziato a collegare "per file obj", riducendo drasticamente le dimensioni binarie. A giudicare dalle dimensioni, devi aver già utilizzato il GHC più recente.

Sul lato positivo, che già hanno un sacco di roba in quelle 500K, come nucleo multithread, garbage collector ecc

aggiungere almeno garbage collector per il codice C, quindi confrontare di nuovo :)

+1

Mentre è vero che il file binario di Haskell contiene molte cose che il file binario C non ha, è inutile averlo se non è usato ... –

+5

@ liw.fi Se sei/che/preoccupato della dimensione dei tuoi eseguibili, C è l'unica lingua abbastanza buona per te. – Rayne

+2

@ liw.fi Haskell è quasi per definizione sulla garbage collection, l'esecuzione multi-core, ecc. Quindi, in effetti, è inutile _non_ avere tutte quelle cose nel core. O lasciarlo fuori (aggiungendo ulteriore sforzo a un nucleo modulare che potrebbe fare proprio questo). E per cosa? Per salvare 100K di dimensione binaria? – ADEpt

6
strip -p --strip-unneeded --remove-section=.comment -o your_executable_small your_executable 

anche provare a guardare LDD -dr your_executable

16

la dimensione che stai vedendo è il runtime Haskell (libHSrts.a), che è staticamente legata in ogni eseguibile Haskell. Se fosse un oggetto condiviso, come librt.o per C, il tuo binario sarebbe solo di pochi k (la dimensione di un file .o di divisione nel sorgente della libreria).

A parte l'implementazione del collegamento dinamico di libHSrts.a sulla piattaforma, è possibile rendere i file eseguibili più piccoli tramite strip.

6

Le cose stanno cambiando - tieni d'occhio il lavoro this in corso.

9

Se la dimensione del file binario è davvero importante, è possibile utilizzare lo strumento gzexe che comprime un file eseguibile (preferibilmente già sottoposto a stripping) con la compressione gzip. Nella mia scatola Linux a 64 bit, il programma originale Hello World richiede 552 KB, dopo aver rimosso 393 KB e dopo aver rimosso e aggiunto 125 KB. Il lato più oscuro del gzipping è in termini di prestazioni: l'eseguibile deve essere prima scompattato.

+2

Non lo sapevo! Questo è un suggerimento davvero utile, avevo un eseguibile da 15 MB che era giù a 7,3 MB dopo ** strip **, ma poi a 1,5 MB dopo ** gzexe **! Ho trovato un altro strumento ** [upx] (http://upx.sourceforge.net/) ** che usato al posto di ** gzexe ** ha ottenuto l'eseguibile a 1,2 MB. –