簡単な答えはありますか:GHCはなぜそれほど大きいのですか?
- OCaml:2 MB
- Python:15 MB
- SBCL:9MB
- OpenJRE-26MB
- GHC:113 MB
「なぜHaskellが適切なツールであるならば、なぜ私はサイズを気にする必要がないのか」という伝道には興味がありません。これは技術的な質問です。
簡単な答えはありますか:GHCはなぜそれほど大きいのですか?
「なぜHaskellが適切なツールであるならば、なぜ私はサイズを気にする必要がないのか」という伝道には興味がありません。これは技術的な質問です。
回答:
ほんと少しばかげています。GHCに付属するすべてのライブラリは、4つ以上のフレーバーで提供されます。
GHCiバージョンは、単一の.o
ファイルにリンクされた静的バージョンです。他の3つのバージョンにも、独自のインターフェイスファイル(.hi
ファイル)のセットがあります。プロファイリングされたバージョンは、プロファイリングされていないバージョンの約2倍のサイズのようです(これは少し疑わしいですが、なぜそうなのかを調べる必要があります)。
GHC自体がライブラリであることを忘れないでください。そのため、GHCの4つのコピーを取得します。それだけでなく、GHCバイナリ自体も静的にリンクされているため、GHCの5つのコピーになります。
最近、GHCiが静的.a
ファイルを使用できるように作成しました。これにより、これらのフレーバーの1つを取り除くことができます。長期的には、GHCを動的にリンクする必要がありますが、これは動的リンクをデフォルトにすることを伴うため、大きな変更です-Cとは異なり、GHCでは動的にリンクするかどうかを前もって決定する必要があります。そして、これが本当に実用的なものになる前に、さらに変更(たとえば、とりわけ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は、ランタイムに静的にリンクされているHaskell helloworldに対して77 MB非圧縮で、1 MB未満です。GHCはここでは大きくありません。
GHCが大きい場合、コンパイルされた開発キットのサイズは次のとおりです。
GHC自体は270 MBを必要とし、すべてのライブラリとユーティリティを組み合わせると500 MBを超えます。そして、はい、ベースライブラリとビルドツール/依存関係マネージャーがあっても、それはたくさんあります。Java開発プラットフォームは小さいです。
GHC:
$ aptitude show ghc6 | grep Size
Uncompressed Size: 388M
OpenJDK withdependenciesに対して:
$ 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
。したがって、答えは、そこにあるすべてのライブラリの静的リンクとプロファイリングバージョンのようです。
これが私のボックスのディレクトリサイズの内訳です。
https://spreadsheets.google.com/ccc?key=0AveoXImmNnZ6dDlQeHY2MmxPcEYzYkpweEtDSS1fUlE&hl=en
最大のディレクトリ(123 MB)は、コンパイラ自体をコンパイルするためのバイナリのようです。ドキュメントの量は驚異的な65 MBです。3位は41 MBのCabalです。
binディレクトリーは33 MBですが、Haskellアプリケーションをビルドするために技術的に必要なのはそのサブセットだけだと思います。
簡単に言えば、すべての実行可能ファイルが静的にリンクされ、デバッグ情報が含まれている可能性があり、ライブラリが複数のコピーに含まれているためです。これはすでに他のコメント者によって言われました。
動的リンクが可能で、サイズが劇的に減少します。次に例を示し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です。