有一个简单的答案:为什么GHC这么大?
对于"如果Haskell是正确的工具,为什么我不应该关心大小"的传福音不感兴趣; 这是一个技术问题.
Sim*_*low 185
这真的有点傻.GHC附带的每个库都提供不少于4种口味:
GHCi版本只是在单个.o
文件中链接在一起的静态版本.其他三个版本也有自己的一组接口文件(.hi
文件).配置文件版本的大小似乎是未经编译的版本的两倍(这有点可疑,我应该研究一下为什么会这样).
请记住,GHC本身就是一个库,所以你得到4份GHC.不仅如此,GHC二进制本身也是静态链接的,因此GHC的5份副本.
我们最近做了这样,GHCi可以使用静态.a
文件.这将使我们摆脱这些风味之一.从长远来看,我们应该动态地链接GHC,但这是一个更大的变化,因为这需要动态链接默认 - 与C不同,GHC你必须事先决定你是否要动态链接.在真正实用之前,我们需要进行更多更改(例如对Cabal和包装系统等).
sas*_*nin 55
可能我们应该比较苹果和苹果,橙子和橙子.JRE是运行时,而不是开发人员工具包.我们可以比较:开发工具包的源大小,编译的开发工具包的大小和最小运行时的编译大小.
OpenJDK 7源包是82 MB(download.java.net/openjdk/jdk7)vs 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.是的,它很多,即使使用基础库和构建工具/依赖管理器也是如此.Java开发平台较小.
GHC:
$ aptitude show ghc6 | grep Size
Uncompressed Size: 388M
Run Code Online (Sandbox Code Playgroud)
与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
Run Code Online (Sandbox Code Playgroud)
但它仍然超过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
Run Code Online (Sandbox Code Playgroud)
请注意有多大libHSghc-6.12.1_p.a
.所以答案似乎是每个库的静态链接和分析版本.
我的猜测 - 很多很多静态链接.每个库都需要静态链接其依赖关系,这依赖关系需要静态链接它们和软件.这些都经常被编译,无论是否有分析,即使没有分析二进制文件也不会被剥离,因此需要保存大量的调试器信息.
因为它捆绑了gcc和一堆库,所有这些都是静态链接的.
至少在Windows上.
这是我的盒子上的目录大小细分:
https://spreadsheets.google.com/ccc?key=0AveoXImmNnZ6dDlQeHY2MmxPcEYzYkpweEtDSS1fUlE&hl=en
看起来最大的目录 (123 MB) 是用于编译编译器本身的二进制文件。这些文件的重量达到惊人的 65 MB。第三名是 Cabal,大小为 41 MB。
bin 目录是 33 MB,我认为只有其中的一个子集是构建 Haskell 应用程序的技术要求。
Short answer is that it's because all executables are statically linked, may have debug info in them and libraries are included in multiple copies. This has already been said by other commenters.
Dynamic linking is possible and will reduce the size dramatically. Here is an example Hello.hs
:
main = putStrLn "Hello world"
Run Code Online (Sandbox Code Playgroud)
I build with GHC 7.4.2 on Windows.
ghc --make -O2
gives Hello.exe
of 1105Ks
Running strip
on it leaves 630K
ghc --make -O2 -dynamic
gives 40K
Stripping it leaves just 13K.
It's dependencies are 5 dlls with total size of 9.2 MBs unstripped and 5.7 MB stripped.