Mengapa GHC begitu besar / besar?

147

Apakah ada jawaban sederhana: Mengapa GHC begitu besar?

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

Tidak tertarik pada penginjilan "Mengapa saya tidak harus peduli tentang ukuran jika Haskell adalah alat yang tepat"; ini pertanyaan teknis.

Christopher Done
sumber
1
Dari mana Anda mendapatkan 500MB ini? GHC saya sangat dekat dengan yang sebesar itu.
Jacob
Kecuali jika Anda menghitung semua perpustakaan, saya kira ...
Jacob
Maaf, saya akan mengunduh paket manager yang mencakup beberapa deps. Saya memperbaruinya untuk mencerminkan ukuran unduhan dari situs web. Saya menambahkan ringkasan Edit tetapi belum muncul di sini (belum?). Saya pikir pertanyaannya masih ada. Itu besar.
Christopher Done
20
Mungkin kita harus membandingkan apel dengan apel dan jeruk dengan jeruk. JRE adalah runtime, bukan kit pengembang. OpenJDK 7 sumber bundel, 82 MB ( download.java.net/openjdk/jdk7 ) vs GHC 7 sumber bundel, 23 MB ( haskell.org/ghc/download_ghc_7_0_1 ). Sekarang runtime: openjdk-6-jre-headless di Ubuntu, 77 MB terkompresi vs Haskell helloworld, secara statis dikaitkan dengan runtime-nya, <1 MB.
sastanin
Hari ini saya ingin tahu tentang ukuran sekarang 2014. Sepertinya argumen masih berlaku. Saya menemukan URL: 1.GHC haskell.org/ghc/download_ghc_7_8_3 ; 2.OpenJCK packages.ubuntu.com/precise/openjdk-7-jdk
AnneTheAgile

Jawaban:

187

Agak konyol sebenarnya. Setiap perpustakaan yang dilengkapi dengan GHC disediakan dalam tidak kurang dari 4 rasa :

  • statis
  • dinamis
  • diprofilkan
  • GHCi

Versi GHCi hanyalah versi statis yang dihubungkan bersama dalam satu .ofile. Tiga versi lainnya semuanya memiliki set sendiri file antarmuka ( .hifile) juga. Versi yang diprofilkan tampaknya berukuran sekitar dua kali lipat dari versi yang tidak diarsipkan (yang agak mencurigakan, saya harus mencari tahu mengapa demikian).

Ingatlah bahwa GHC itu sendiri adalah sebuah perpustakaan , jadi Anda mendapatkan 4 salinan GHC. Tidak hanya itu, tetapi biner GHC itu sendiri terhubung secara statis, jadi itu adalah 5 salinan GHC.

Kami baru-baru ini membuatnya sehingga GHCi dapat menggunakan .afile statis . Itu akan memungkinkan kita untuk menyingkirkan salah satu dari rasa ini. Jangka panjang, kita harus secara dinamis menghubungkan GHC, tetapi itu adalah perubahan yang lebih besar karena itu akan memerlukan pembuatan tautan dinamis yang default - tidak seperti dalam C, dengan GHC Anda harus memutuskan di muka apakah Anda akan menghubungkan secara dinamis atau tidak. Dan kami membutuhkan lebih banyak perubahan (misalnya untuk Cabal dan sistem paket, di antara hal-hal lain) sebelum ini benar-benar praktis.

Simon Marlow
sumber
16
Dan di sini saya pikir itu semua logika yang ditawarkan Haskell: evaluasi malas, inferensi tipe, dll.
mcandre
4
Jadi, 113MB / 4 ~ = 28MB, masih lebih besar dari OpenJRE ... Tapi anggap GHC sebanding dengan OpenJDK, bukan hanya JRE, itu membuat saya merasa lebih baik.
Earth Engine
1
Sekarang saya pikir GHC menggunakan penghubung dinamis, mungkin ide-ide Dr.Simon Marlow untuk kompresi empat rasa lebih praktis? Mengutip: 1. # 3658 (Secara dinamis menghubungkan GHCi (dan menggunakan penghubung sistem) pada platform yang mendukungnya) - GHC ghc.haskell.org/trac/ghc/ticket/3658 ; 2. # 8266 (Tautan dinamis pada Mac) - GHC ghc.haskell.org/trac/ghc/ticket/8266 ; 3. # 8376 (Static Executable + GHC API (+ Dynamic Linking?) Memberikan Segfault) - GHC
AnneTheAgile
56

Mungkin kita harus membandingkan apel dengan apel dan jeruk dengan jeruk. JRE adalah runtime, bukan kit pengembang. Kita dapat membandingkan: ukuran sumber kit pengembangan, ukuran kit pengembangan yang dikompilasi dan ukuran yang dikompilasi dari runtime minimal.

Bundel sumber OpenJDK 7 adalah 82 MB (unduh.java.net/openjdk/jdk7) vs bundel sumber GHC 7, yaitu 23 MB (haskell.org/ghc/download_ghc_7_0_1). GHC tidak besar di sini. Ukuran runtime: openjdk-6-jre-headless di Ubuntu adalah 77 MB terkompresi vs Haskell helloworld, secara statis dikaitkan dengan runtime-nya, yaitu <1 MB. GHC tidak besar di sini.

Di mana GHC besar, adalah ukuran kit pengembangan yang dikompilasi:

Penggunaan disk GHC

GHC sendiri membutuhkan 270 MB, dan dengan semua perpustakaan dan utilitas yang menyatukannya dibutuhkan lebih dari 500 MB. Dan ya, banyak, bahkan dengan pustaka dasar dan pengelola alat / dependensi. Platform pengembangan Java lebih kecil.

GHC:

$ aptitude show ghc6 | grep Size
Uncompressed Size: 388M

terhadap OpenJDK penarikan kembali:

$ 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

Tapi itu masih lebih dari 100 MB, bukan 26 MB saat Anda menulis.

Hal-hal berat dalam ghc6 dan ghc6-prof adalah:

$ 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

Harap perhatikan seberapa besar libHSghc-6.12.1_p.a. Jadi jawabannya tampaknya menghubungkan statis dan membuat profil versi untuk setiap perpustakaan di luar sana.

sastanin
sumber
9

Tebakan saya - banyak dan banyak tautan statis. Setiap perpustakaan perlu menghubungkan secara dependensi ketergantungannya secara statis, yang pada gilirannya perlu menghubungkannya secara statis dan lebih lunak. Dan ini semua sering dikompilasi baik dengan dan tanpa profil, dan bahkan tanpa profil biner tidak dilucuti dan begitu banyak informasi debugger.

sclv
sumber
2
Saya mungkin tidak akan keberatan jika GHC beralih ke seluruh program, mengkompilasi ulang hampir semua model, mirip dengan jhc. Bahkan mungkin mengkompilasi lebih cepat jika itu akan menjaga 'ld' dari swapping.
John L
8

Karena bundel itu gcc dan banyak perpustakaan, semuanya terhubung secara statis.

Setidaknya di Windows.

Marko
sumber
12
tidak, bukan di linux. itu hanya tergantung pada gcc. karena windows tidak memiliki gcc dalam "distribusinya", ia harus disertai dengan ghc.
comonad
5

Berikut ini rincian ukuran direktori pada kotak saya:

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

Sepertinya direktori terbesar (123 MB) adalah binari untuk kompilasi kompilator itu sendiri. Dokumen berbobot 65 MB. Tempat ketiga adalah Cabal pada 41 MB.

Direktori bin adalah 33 MB, dan saya pikir hanya sebagian yang diperlukan secara teknis untuk membangun aplikasi Haskell.

Yakub
sumber
6
Izinkan saya menambahkan sesuatu ke ini: Jika Anda hanya mengambil kompiler barebone dan menghapus apa pun yang tidak benar-benar diperlukan, (seperti membangun kompiler yang belum diprofilkan, dilucuti dll), Anda dapat turun hingga sekitar 5 MB. Tapi coba bandingkan ukuran kompiler dengan GCC. (Mengedit komentar, jadi saya harus menghapusnya ... maaf)
fuz
5

Jawaban singkatnya adalah karena semua executable terhubung secara statis, mungkin memiliki info debug di dalamnya dan pustaka disertakan dalam banyak salinan. Ini sudah dikatakan oleh komentator lain.

Tautan dinamis dimungkinkan dan akan mengurangi ukuran secara dramatis. Berikut ini sebuah contoh Hello.hs:

main = putStrLn "Hello world"

Saya membangun dengan GHC 7.4.2 di Windows.

ghc --make -O2memberikan Hello.exe1105Ks

Berjalan stripdi atasnya meninggalkan 630K

ghc --make -O2 -dynamic memberi 40K

Pengupasan itu menyisakan hanya 13 ribu.

Ketergantungannya adalah 5 dll dengan ukuran total 9,2 MB unstripped dan 5,7 MB stripped.

nponeccop
sumber