ChatGPT解决这个技术问题 Extra ChatGPT

为什么 GHC 这么大/大?

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

OCaml:2MB

蟒蛇:15MB

SBCL:9MB

OpenJRE - 26MB

GHC:113MB

对“如果 Haskell 是正确的工具,为什么我不应该关心大小”的宣传不感兴趣;这是一个技术问题。

你从哪里得到这 500MB?我的 GHC 远没有那么大。
除非你算上所有的图书馆,我猜......
抱歉,我正在下载包含一些依赖项的包管理器。我更新了它以反映网站的下载大小。我添加了一个编辑摘要,但它没有出现在这里(还没有?)。我认为问题仍然存在。它很大。
或许我们应该将苹果与苹果、橙子与橙子进行比较。 JRE 是一个运行时,而不是一个开发工具包。 OpenJDK 7 源包,82 MB (download.java.net/openjdk/jdk7) 与 GHC 7 源包,23 MB (haskell.org/ghc/download_ghc_7_0_1)。现在运行时:Ubuntu 上的 openjdk-6-jre-headless,77 MB 未压缩 vs Haskell helloworld,与其运行时静态链接,<1 MB。
今天我很好奇现在 2014 年的尺寸。看来这个论点仍然成立。我找到了网址:1.GHC haskell.org/ghc/download_ghc_7_8_3; 2.OpenJCK packages.ubuntu.com/precise/openjdk-7-jdk

S
Simon Marlow

真的有点傻。 GHC 附带的每个库都提供不少于 4 种风格:

静止的

动态的

异形

GHCI

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

请记住,GHC 本身就是一个库,因此您将获得 4 个 GHC 副本。不仅如此,GHC 二进制文件本身也是静态链接的,所以这是 GHC 的 5 个副本。

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


在这里,我认为这是 Haskell 提供的所有逻辑:惰性求值、类型推断等。
所以,113MB / 4 ~= 28MB,还是比 OpenJRE 大……但是考虑到 GHC 可以和 OpenJDK 媲美,而不仅仅是 JRE,这让我感觉更好。
现在我认为 GHC 使用动态链接,也许@Simon Marlow 博士关于压缩四种口味的想法更实用?引用:1.#3658(在支持它的平台上动态链接 GHCi(并使用系统链接器))– GHC ghc.haskell.org/trac/ghc/ticket/3658; 2.#8266 (Mac 上的动态链接) – GHC ghc.haskell.org/trac/ghc/ticket/8266 ; 3.#8376 (Static Executable + GHC API (+ Dynamic Linking?) 给出 Segfault) – GHC
s
sastanin

或许我们应该将苹果与苹果、橙子与橙子进行比较。 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 大的地方,就是编译后的开发包的大小:

https://i.stack.imgur.com/nc0Cs.png

GHC 本身占用 270 MB,加上所有库和实用程序,它占用了超过 500 MB。是的,它很多,即使有基础库和构建工具/依赖管理器。 Java开发平台更小。

温室气体:

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


s
sclv

我的猜测——大量的静态链接。每个库都需要静态链接其依赖项,而这些依赖项又需要静态链接它们的依赖项等等。这通常都是在有和没有分析的情况下编译的,即使没有分析,二进制文件也不会被剥离,因此会保存大量的调试器信息。


我可能不介意 GHC 切换到整个程序,重新编译几乎所有模型,类似于 jhc。如果它能让 'ld' 不被交换,它甚至可能编译得更快。
M
Marko

因为它捆绑了 gcc 和一堆库,都是静态链接的。

至少在 Windows 上。


不,不在Linux上。它只取决于 gcc。因为windows在其“发行版”中没有gcc,所以它必须附带ghc。
好吧,更迂腐一点,这是因为 Windows 有 rpm 但没有 yum,所以没有简单的方法来获取依赖项,所以每个应用程序只是以 Docker/Snap 方式捆绑其所有依赖项。 MSI 依赖项也存在,但由于 MSI 的过度设计而几乎从未使用过。如果最终采用新的包装技术(可能是 AppX 的继任者),这种情况可能会改变
J
Jacob

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

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

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

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


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

简短的回答是,这是因为所有可执行文件都是静态链接的,其中可能包含调试信息,并且库包含在多个副本中。其他评论者已经说过了。

动态链接是可能的,并将显着减小大小。这是一个示例 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。


ghc 版本 9.0.1,Hello.exe 为 11,880,549 字节。 8.x 版略少,徘徊在 10MB 左右。
在 ubuntu 上,它生成的图像大小为 896,168(静态)。 16,592 与 -dynamic。 -dynamic 在 Windows 上不起作用。
7.6.3 是最后一个发布动态 base 的 GHC 版本。然后动态链接由于各种原因被破坏,然后他们部分修复了它,所以现在可以制作动态的 hello world,但是你必须在支持下构建自己的 GHC,因为自 7.6.3 以来经过这么多年,它还没有准备好生产.另外,你能找到剥离的尺寸吗?