有一个简单的答案:GHC为什么这么大?
- OCaml:2MB
- 的Python:15MB
- SBCL:9MB
- OpenJRE-26MB
- GHC:113MB
对“为什么Haskell是正确的工具,为什么我不应该关心大小”的布道不感兴趣;这是一个技术问题。
有一个简单的答案:GHC为什么这么大?
对“为什么Haskell是正确的工具,为什么我不应该关心大小”的布道不感兴趣;这是一个技术问题。
Answers:
真的有点傻。每个随附GHC的库都提供了至少4种口味:
GHCi版本只是在单个.o
文件中链接在一起的静态版本。其他三个版本也都有自己的一组接口文件(.hi
file)。概要文件版本似乎是未概要文件版本的两倍(这有点可疑,我应该研究为什么)。
请记住,GHC本身是一个库,因此您将获得4份GHC副本。不仅如此,GHC二进制文件本身也是静态链接的,因此这是GHC的5个副本。
我们最近做到了这一点,以便GHCi可以使用静态.a
文件。这将使我们摆脱这些味道之一。从长远来看,我们应该动态链接GHC,但这是一个更大的变化,因为这将需要使动态链接成为默认链接-与C语言不同,与GHC不同,您必须预先决定是否要动态链接。在此切实可行之前,我们需要进行更多更改(例如,对Cabal和包装系统进行更改)。
也许我们应该将苹果与苹果进行比较,将桔子与橙进行比较。JRE是运行时,而不是开发人员工具包。我们可以比较一下:开发套件的源大小,已编译的开发套件的大小和最小运行时的已编译大小。
OpenJDK 7源包为82 MB(download.java.net/openjdk/jdk7),而GHC 7源包为23 MB(haskell.org/ghc/download_ghc_7_0_1)。GHC在这里并不大。运行时大小:Ubuntu上的openjdk-6-jre-headless未压缩,而Haskell helloworld则为77 MB,与运行时静态链接,小于1 MB。GHC在这里并不大。
GHC大的地方是编译后的开发套件的大小:
GHC本身占用270 MB,而所有库和实用程序加在一起则占用500 MB以上。是的,即使有了基础库和构建工具/依赖管理器,它也很多。Java开发平台较小。
GHC:
$ aptitude show ghc6 | grep Size
Uncompressed Size: 388M
针对OpenJDK独立性:
$ aptitude show openjdk-6-jdk openjdk-6-jre openjdk-6-jre-headless ant maven2 ivy | grep Size
Uncompressed Size: 34.9M
Uncompressed Size: 905k
Uncompressed Size: 77.3M
Uncompressed Size: 1,585k
Uncompressed Size: 3,736k
Uncompressed Size: 991k
但是它仍然超过100 MB,而不是您编写时的26 MB。
ghc6和ghc6-prof中的重量级内容包括:
$ dpkg -L ghc6 | grep '\.a$' | xargs ls -1ks | sort -k 1 -n -r | head -3
57048 /usr/lib/ghc-6.12.1/ghc-6.12.1/libHSghc-6.12.1.a
22668 /usr/lib/ghc-6.12.1/Cabal-1.8.0.2/libHSCabal-1.8.0.2.a
21468 /usr/lib/ghc-6.12.1/base-4.2.0.0/libHSbase-4.2.0.0.a
$ dpkg -L ghc6-prof | grep '\.a$' | xargs ls -1ks | sort -k 1 -n -r | head -3
112596 /usr/lib/ghc-6.12.1/ghc-6.12.1/libHSghc-6.12.1_p.a
33536 /usr/lib/ghc-6.12.1/Cabal-1.8.0.2/libHSCabal-1.8.0.2_p.a
31724 /usr/lib/ghc-6.12.1/base-4.2.0.0/libHSbase-4.2.0.0_p.a
请注意有多大libHSghc-6.12.1_p.a
。因此,答案似乎是那里每个库的静态链接和配置文件版本。
这是我的盒子上的目录大小明细:
https://spreadsheets.google.com/ccc?key=0AveoXImmNnZ6dDlQeHY2MmxPcEYzYkpweEtDSS1fUlE&hl=zh-CN
看起来最大的目录(123 MB)是用于编译编译器本身的二进制文件。文件重达惊人的65 MB。第三名是Cabal,容量为41 MB。
bin目录为33 MB,我认为其中只有一部分是构建Haskell应用程序的技术要求。
简短的答案是,因为所有可执行文件都是静态链接的,可能其中包含调试信息,并且库包含在多个副本中。其他评论者已经说过这一点。
动态链接是可能的,并且将大大减小尺寸。这是一个例子Hello.hs
:
main = putStrLn "Hello world"
我在Windows上使用GHC 7.4.2构建。
ghc --make -O2
给出Hello.exe
1105Ks
strip
在其上运行可剩下630K
ghc --make -O2 -dynamic
给出40K
剥离它仅剩下13K。
它的依存关系是5个dll,它们的总大小为9.2 MB(未剥离)和5.7 MB(剥离)。