web-dev-qa-db-ja.com

GHCが非常に大きい/大きいのはなぜですか?

簡単な答えはありますか?なぜGHCはそんなに大きいのですか?

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

「Haskellが適切なツールである場合、なぜ私はサイズを気にするべきではない」という伝道には興味がない。これは技術的な質問です。

145

ちょっとばかげている。 GHCに付属するすべてのライブラリは4 flavours以上で提供されます:

  • 静的
  • 動的
  • プロファイリング
  • GHCi

GHCiバージョンは、単一の.oファイル。他の3つのバージョンはすべて、独自のインターフェイスファイルのセット(.hiファイルも)。プロファイルされたバージョンは、プロファイルされていないバージョンの約2倍のサイズのようです(少し疑わしいので、その理由を調べてください)。

GHC自体はライブラリであるため、GHCの4つのコピーを取得していることに注意してください。それだけでなく、GHCバイナリ自体が静的にリンクされているため、GHCの5つのコピーです。

GHCiがstatic .aファイル。これにより、これらのフレーバーの1つを取り除くことができます。長期的には、GHCを動的にリンクする必要がありますが、Cとは異なり、GHCでは動的にリンクするかどうかを事前に決定する必要があるため、デフォルトを動的にリンクする必要があるため、大きな変更です。そして、これが実際に実行される前に、さらに変更が必要です(たとえば、特にCabalやパッケージシステムなど)。

183
Simon Marlow

おそらくリンゴとリンゴを比較し、オレンジとオレンジを比較する必要があります。 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非圧縮vs Haskell helloworldであり、そのランタイムと静的にリンクしています(1 MB未満)。 GHCはここでは大きくありません。

GHCが大きい場合、コンパイルされた開発キットのサイズは次のとおりです。

GHC disk usage

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。したがって、答えは、そこにあるすべてのライブラリの静的リンクとプロファイリングのバージョンのようです。

55
sastanin

私の推測-たくさんの静的リンク。各ライブラリは、依存関係を静的にリンクする必要があり、依存関係は、それらの依存関係を静的にリンクする必要があります。そして、これはすべてプロファイリングありとプロファイリングなしの両方でコンパイルされることが多く、プロファイリングなしでもバイナリは削除されないため、多くのデバッガ情報が保持されます。

9
sclv

gccとライブラリの束をバンドルしているため、すべて静的にリンクされています。

少なくともWindowsでは。

8
Marko

簡単な答えは、すべての実行可能ファイルが静的にリンクされ、デバッグ情報が含まれている可能性があり、ライブラリが複数のコピーに含まれているためです。これはすでに他のコメンターによって言われています。

動的リンクが可能であり、サイズを劇的に削減します。次に例を示しますHello.hs

main = putStrLn "Hello world"

WindowsでGHC 7.4.2を使用してビルドします。

ghc --make -O2Hello.exe of 1105Ks

stripを実行すると630Kが残ります

ghc --make -O2 -dynamicは40Kを与える

ストリップすると、わずか13Kになります。

依存関係は5つのdllであり、合計サイズは9.2 MBが削除されておらず、5.7 MBが削除されています。

5
nponeccop

ボックスのディレクトリサイズの内訳は次のとおりです。

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

最大のディレクトリ(123 MB)は、コンパイラ自体をコンパイルするためのバイナリのようです。文書は65 MBという驚異的な大きさです。 3位はCabalで41 MBです。

Binディレクトリは33 MBであり、Haskellアプリケーションを構築するために技術的に必要なのはそのサブセットのみだと思います。

4
Jacob