为什么GHC这么大/大?

Chr*_*one 145 haskell ghc

有一个简单的答案:为什么GHC这么大?

  • OCaml:2MB
  • Python:15MB
  • SBCL:9MB
  • OpenJRE - 26MB
  • GHC:113MB

对于"如果Haskell是正确的工具,为什么我不应该关心大小"的传福音不感兴趣; 这是一个技术问题.

Sim*_*low 185

这真的有点傻.GHC附带的每个库都提供不少于4种口味:

  • 静态的
  • 动态
  • 异形
  • GHCI

GHCi版本只是在单个.o文件中链接在一起的静态版本.其他三个版本也有自己的一组接口文件(.hi文件).配置文件版本的大小似乎是未经编译的版本的两倍(这有点可疑,我应该研究一下为什么会这样).

请记住,GHC本身就是一个库,所以你得到4份GHC.不仅如此,GHC二进制本身也是静态链接的,因此GHC的5份副本.

我们最近做了这样,GHCi可以使用静态.a文件.这将使我们摆脱这些风味之一.从长远来看,我们应该动态地链接GHC,但这是一个更大的变化,因为这需要动态链接默认 - 与C不同,GHC你必须事先决定你是否要动态链接.在真正实用之前,我们需要进行更多更改(例如对Cabal和包装系统等).

  • 在这里,我认为这是Haskell提供的所有逻辑:懒惰评估,类型推断等. (16认同)
  • 所以,113MB/4~ = 28MB,仍然比OpenJRE大......但是考虑到GHC可以与OpenJDK相媲美,而不仅仅是JRE,它让我感觉更好. (4认同)

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

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.所以答案似乎是每个库的静态链接和分析版本.


scl*_*clv 9

我的猜测 - 很多很多静态链接.每个库都需要静态链接其依赖关系,这依赖关系需要静态链接它们和软件.这些都经常被编译,无论是否有分析,即使没有分析二进制文件也不会被剥离,因此需要保存大量的调试器信息.

  • 我可能不介意GHC是否切换到整个程序,重新编译几乎所有模型,类似于jhc。如果可以防止交换“ ld”,它甚至可以编译得更快。 (2认同)

Mar*_*rko 8

因为它捆绑了gcc和一堆库,所有这些都是静态链接的.

至少在Windows上.

  • 不,不是在linux上.它只取决于gcc.因为windows的"发行版"中没有gcc,所以它必须带有ghc. (12认同)

Jac*_*cob 5

这是我的盒子上的目录大小细分:

https://spreadsheets.google.com/ccc?key=0AveoXImmNnZ6dDlQeHY2MmxPcEYzYkpweEtDSS1fUlE&hl=en

看起来最大的目录 (123 MB) 是用于编译编译器本身的二进制文件。这些文件的重量达到惊人的 65 MB。第三名是 Cabal,大小为 41 MB。

bin 目录是 33 MB,我认为只有其中的一个子集是构建 Haskell 应用程序的技术要求。

  • 让我补充一点:如果你只使用准系统编译器并剥离任何不是绝对需要的东西(比如构建未配置的编译器、剥离等),你可以减少到大约 5 MB。但是尝试将编译器的大小与 GCC 进行比较。(编辑了评论,所以我不得不删除它......抱歉) (6认同)

npo*_*cop 5

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.