2009-03-31 29 views
39

¿Hay alguna buena forma de hacer pequeños ejecutables haskell? Con ghc6, un simple programa hello world parece llegar a unos 370kB (523kB antes de la tira). Hola mundo en C es de aproximadamente 4kB (9kB antes de la tira).Hacer pequeños ejecutables haskell?

+0

Utilice la vinculación dinámica, como se describe aquí, http: // stackoverflow.com/questions/6115459/small-haskell-program-compiled-with-ghc-in-huge-binary –

Respuesta

44

Con la rama de desarrollo de GHC (nadie sabe exactamente qué versión esto se añadió en?):

$ 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 

Añadir la bandera -dynamic durante estrategia en tiempo real de enlace dinámico:

$ 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 

Véase también : http://hackage.haskell.org/trac/ghc/wiki/SharedLibraries/PlatformSupport

Para la comparación con 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

Funciona para mí en ghc 6.12.1. – Joe

+0

Si obtiene el error "Tal vez no haya instalado las bibliotecas de creación de perfiles para el paquete 'base'", entonces apt-get install ghc-dynamic. – matcheek

+0

¿cuál sería el comando 'strip' equivalente en OS X? –

8

Debe contar sus bendiciones (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$ 

Hablando en serio, mientras que es probable que pueda sacudir Haskell Binarios un poco, en realidad no es una comparación justa con C. Hay una más que hacer allí .

La última vez que jugué con ghc (y esto podría estar desactualizado) estaba vinculando estáticamente todo, lo que será un factor.

21

GHC está vinculando estáticamente todo (excepto las bibliotecas utilizadas por el propio tiempo de ejecución, que están vinculadas dinámicamente).

En la vejez, GHC vinculó la biblioteca completa (haskell) tan pronto como usó algo de ella. Hace algún tiempo, GHC comenzó a vincular "por archivo obj", lo que redujo drásticamente el tamaño del binario. A juzgar por el tamaño, debes haber estado usando el GHC más nuevo.

En el lado positivo, que ya tienen un montón de cosas en los 500K, como núcleo de multiproceso, recolector de basura, etc.

Añadir al menos recolector de basura para su código C, luego compararlas nuevo :)

+1

Si bien es cierto que el binario Haskell contiene muchas cosas que el binario C no tiene, no tiene sentido tenerlo si no se usa ... –

+5

@ liw.fi Si está/eso/preocupado por el tamaño de sus ejecutables, C es el único lenguaje lo suficientemente bueno para usted. – Rayne

+2

@ liw.fi Haskell es casi por definición sobre recolección de basura, ejecución de múltiples núcleos, etc. Por lo tanto, de hecho, no tiene sentido tener todas esas cosas en el núcleo. O déjalo fuera (aplicando un esfuerzo adicional en el núcleo modular que podría hacerlo). ¿Y para qué? Para guardar 100K de tamaño binario? – ADEpt

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

también intente buscar en LDD -dr your_executable

16

el tamaño que se está viendo es el tiempo de ejecución de Haskell (libHSrts.a), que está vinculado estáticamente en cada ejecutable Haskell. Si fuera un objeto compartido, como librt.o para C, su binario sería solo de unos k (el tamaño de un archivo .o dividido en el origen de la biblioteca).

A falta de implementar el enlace dinámico de libHSrts.a en su plataforma, puede hacer que sus ejecutables sean más pequeños a través de la tira.

6

Las cosas están cambiando: no se pierda this en curso de trabajo.

9

Si el tamaño de su binario realmente importa, puede usar la herramienta gzexe que contiene un ejecutable (preferiblemente ya eliminado) con la compresión gzip. En mi caja de Linux de 64 bits, el programa original hello world toma 552 KB, después de pelar 393 KB, y después de pelar y gzip 125 KB. El lado más oscuro de gzipping está en el rendimiento: primero hay que desempaquetar el archivo ejecutable.

+2

¡No sabía de esto! Esa es una sugerencia realmente útil, tenía un ejecutable de 15 MB que se redujo a 7.3 MB después de ** tira **, pero luego bajó a 1.5 MB después de ** gzexe **! Encontré otra herramienta ** [upx] (http://upx.sourceforge.net/) ** que se usó en lugar de ** gzexe ** obtuvo el ejecutable hasta 1.2 MB. –

Cuestiones relacionadas