【发布时间】:2012-09-25 00:19:24
【问题描述】:
可能重复:
Small Haskell program compiled with GHC into huge binary
最近我注意到 Haskell 可执行文件有多大。以下所有内容均在 GHC 7.4.1 上编译,在 Linux 上使用 -O2。
Hello World (
main = putStrLn "Hello World!") 超过 800 KiB。在其上运行strip会将文件大小减少到 500 KiB;即使在编译中添加-dynamic也无济于事,只剩下大约 400 KiB 的剥离可执行文件。-
编译一个涉及 Parsec 的非常原始的示例会生成一个 1.7 MiB 的文件。
-- File: test.hs import qualified Text.ParserCombinators.Parsec as P import Data.Either (either) -- Parses a string of type "x y" to the tuple (x,y). testParser :: P.Parser (Char, Char) testParser = do a <- P.anyChar P.char ' ' b <- P.anyChar return (a, b) -- Parse, print result. str = "1 2" main = print $ either (error . show) id . P.parse testParser "" $ str -- Output: ('1','2')Parsec 可能是一个更大的库,但我只使用了它的一小部分,实际上由上面生成的优化核心代码比可执行文件要小得多:
$ ghc -O2 -ddump-simpl -fforce-recomp test.hs | wc -c 49190 (bytes)因此,程序中并没有实际发现大量 Parsec,这是我最初的假设。
为什么可执行文件如此庞大?有什么我可以做的吗(动态链接除外)?
【问题讨论】:
-
@DanielWagner 另一个问题当然是相关的,但即使使用那里描述的技术 Hello World 仍然是巨大的。另外:为什么应该包含整个程序的小核心代码在编译时会变得如此之大?
-
有一个相当大的运行时系统。
-
@David:核心不包含整个程序,除非所有内容都被内联,这是不太可能的。所以它将在 Parsec 中链接,除非你使用
-split-objs构建它(请参阅 related answer),否则它必须链接所有这些。 -
作为参考,您的原始示例在我的系统上生成了 29 KiB "big" 可执行文件。
ghc -O2 -dynamic test.hs && strip test && du -b test=> 28712 字节。 GHC 7.4.2 版本,x86_64 Linux 系统。
标签: haskell compilation ghc