为什么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磁盘使用情况

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应用程序所需的技术。