为什么GHC这么大/大?
有一个简单的答案:为什么GHC这么大?
- OCaml:2MB
- Python:15MB
- SBCL:9MB
- OpenJRE – 26MB
- GHC:113MB
对“如果Haskell是正确的工具,为什么我不应该关心它的大小”这个传福音不感兴趣; 这是一个技术问题。
这真的有点傻。 GHC提供的每个图书馆都提供不less于4种口味 :
- 静态的
- dynamic
- 异形
- GHCI
GHCi版本只是在一个.o
文件中链接在一起的静态版本。 其他三个版本都有自己的一套接口文件( .hi
文件)。 configuration文件的版本似乎大约是未打稿版本的两倍(这有点可疑,我应该考虑这是为什么)。
请记住, GHC本身就是一个图书馆 ,所以你得到4份GHC。 不仅如此,GHC二进制本身是静态链接的,所以这是GHC的5个副本。
我们最近做了这个,让GHCi可以使用静态的.a
文件。 这将使我们摆脱这些风味之一。 从长远来看,我们应该dynamic链接GHC,但这是一个更大的变化,因为这需要dynamic链接默认 – 不像C,与GHC,你必须决定是否要dynamic链接。 而且我们需要更多的改变(例如在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是77 MB未压缩的Haskell helloworld,静态链接到它的运行时间,<1 MB。 GHC在这里不是很大。
GHC大的地方是编译开发工具包的大小:
GHC本身需要270 MB,并且所有库和实用程序组合在一起需要超过500 MB。 是的,即使有基础库和构build工具/依赖pipe理器也是如此。 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
。 所以答案似乎是静态链接和分析版本为每个图书馆。
我的猜测 – 很多很多的静态链接。 每个库都需要静态链接它的依赖关系,而这又需要静态链接它们和soforth。 而且这一切都编译通常都有和没有分析,甚至没有分析二进制文件没有被剥离,因此掌握大量的debugging信息。
因为它捆绑了gcc和一堆库,都是静态链接的。
至less在Windows上。
简单的答案是,这是因为所有的可执行文件都是静态链接的,可能有debugging信息,库包含在多个副本中。 其他评论者已经说过这一点。
dynamic链接是可能的,并将显着减小大小。 这里是一个例子Hello.hs
:
main = putStrLn "Hello world"
我在Windows上使用GHC 7.4.2构build。
ghc --make -O2
给出1105K的Hello.exe
在它上面运行的strip
离开630K
ghc --make -O2 -dynamic
给出了40K
剥离只剩下13K。
它的依赖关系是5个dll,总大小为9.2 MB,未剥离,5.7 MB剥离。
这里是我的方块目录大小细分:
https://spreadsheets.google.com/ccc?key=0AveoXImmNnZ6dDlQeHY2MmxPcEYzYkpweEtDSS1fUlE&hl=en
它看起来像最大的目录(123 MB)是编译器本身的二进制文件。 这些文件重达65 MB。 第三名是41 MB的Cabal。
bin目录是33 MB,我认为只有一小部分是构buildHaskell应用程序所需的技术。