简体   繁体   English

制作小的haskell可执行文件?

[英]Making small haskell executables?

Are there any good ways to make small haskell executables? 有没有什么好方法可以制作小的haskell可执行文件? With ghc6 a simple hello world program seems to come to about 370kB (523kB before strip). 使用ghc6,一个简单的hello world程序似乎达到了370kB(在strip之前为523kB)。 Hello world in C is about 4kB (9kB before strip). C中的Hello世界大约是4kB(剥离前9kB)。

With the development branch of GHC (anyone know exactly which version this was added in?): 有了GHC的开发分支(任何人都知道这个版本到底添加了哪个版本?):

$ 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

Add the -dynamic flag for a dynamically linked RTS: 为动态链接的RTS添加-dynamic标志:

$ 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

See also: http://hackage.haskell.org/trac/ghc/wiki/SharedLibraries/PlatformSupport 另见: http//hackage.haskell.org/trac/ghc/wiki/SharedLibraries/PlatformSupport

For comparison with C: 与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

GHC is statically linking everything (except libraries used by runtime itself, which are linked dynamically). GHC静态链接所有内容(运行时本身使用的库除外,它们是动态链接的)。

In the old ages, GHC linked the whole (haskell) library in as soon as you've used something from it. 在旧时代,GHC会在你使用它的时候将整个(haskell)库连接起来。 Sometime ago, GHC started to link "per obj file", which drastically reduced the binary size. 前段时间,GHC开始链接“per obj file”,这大大减少了二进制文件的大小。 Judging from the size, you must've been using the newer GHC already. 从尺寸来看,你一定是在使用更新的GHC。

On the plus side, you already have a lot of stuff in those 500K, like multithreaded core, garbage collector etc. 从好的方面来说,你已经拥有500K的很多东西,比如多线程核心,垃圾收集器等。

Add at least garbage collector to your C code, then compare them again :) 至少将垃圾收集器添加到C代码中,然后再次比较它们:)

The size you're seeing is the Haskell runtime (libHSrts.a), which is statically linked into every Haskell executable. 您看到的大小是Haskell运行时(libHSrts.a),它静态链接到每个Haskell可执行文件。 If it were a shared object, like librt.o for C, your binary would be only a few k (the size of a split .o file in the library source). 如果它是一个共享对象,比如librt.o for C,那么你的二进制文件只有几k(库源中的分割.o文件的大小)。

Short of implementing dynamic linking of libHSrts.a on your platform, you can make your executables smaller via strip. 如果没有在您的平台上实现libHSrts.a的动态链接,您可以通过strip使您的可执行文件更小。

If the size of your binary really matters, you can use the tool gzexe that packs an (preferably already stripped) executable with the gzip compression. 如果你的二进制文件的大小真的很重要,你可以使用工具gzexe包含一个(最好已经剥离)可执行文件和gzip压缩。 On my 64-bit Linux box, the original hello world program takes 552 KB, after stripping 393 KB, and after stripping and gzipping 125 KB. 在我的64位Linux机器上,原始的hello world程序在剥离393 KB后以及剥离和gzipping 125 KB之后需要552 KB。 The darker side of gzipping is in performance -- the executable has to be unpacked first. gzipping的较暗的一面是性能 - 必须首先解压缩可执行文件。

You should count your blessings (370Kb? Luuuxury) : 你应该算上你的祝福(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$

Seriously though while you can probably shake out haskell binaries a bit, it's really not a fair comparison with C. There's a more going on there. 说真的,虽然你可能会稍微改掉一下haskell二进制文件,但它与C的公平比较真的不是。那里还有更多。

Last time I played with ghc (and this might be out of date) it was statically linking everything, which will be a factor. 上次我玩ghc(这可能已经过时),它静态地链接了所有内容,这将是一个因素。

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

也试着看看ldd -dr your_executable

事情正在发生变化 - 密切关注这项持续的工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM