GHC neden bu kadar büyük / büyük?


146

Basit bir cevap var mı: GHC neden bu kadar büyük?

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

"Haskell doğru araçsa boyutu neden umursamamalıyım" evanjelizmiyle ilgilenmiyorum; bu teknik bir sorudur.


1
Bu 500MB'yi nereden alıyorsunuz? Benim GHC'm o kadar büyük değil.
Jacob

Tüm kütüphaneleri saymazsanız, sanırım ...
Yakup

Üzgünüm, bazı depolar içeren bir paket yöneticisi indirmesinden çıkıyordum. Web sitesinden indirme boyutunu yansıtacak şekilde güncelledim. Bir düzenleme özeti ekledim ancak burada görünmedi (henüz?). Sanırım soru hala geçerli. Bu büyük.
Christopher Done

20
Muhtemelen elmaları elmalarla ve portakalları portakallarla karşılaştırmalıyız. JRE, bir geliştirici kiti değil, bir çalışma zamanıdır. OpenJDK 7 kaynak paketi, 82 MB ( download.java.net/openjdk/jdk7 ) - GHC 7 kaynak paketi, 23 MB ( haskell.org/ghc/download_ghc_7_0_1 ). Şimdi çalışma zamanı: Ubuntu'da openjdk-6-jre-headless, 77 MB sıkıştırılmamış vs Haskell helloworld, çalışma zamanıyla statik olarak bağlantılı, <1 MB.
sastanin

Bugün, şimdi 2014 ebatlarını merak ettim. Tartışma hala geçerli gibi görünüyor. URL'leri buldum: 1.GHC haskell.org/ghc/download_ghc_7_8_3 ; 2.OpenJCK packages.ubuntu.com/precise/openjdk-7-jdk
AnneTheAgile

Yanıtlar:


187

Gerçekten biraz aptalca. GHC ile birlikte gelen her kitaplık en az 4 çeşitte sağlanır :

  • statik
  • dinamik
  • profilli
  • GHCi

GHCi sürümü, tek bir .odosyada birbirine bağlanmış statik sürümdür . Diğer üç sürümün de kendi arabirim dosyaları ( .hidosyaları) vardır. Profilli sürümler, profilsiz sürümlerin yaklaşık iki katı boyutta görünüyor (bu biraz şüpheli, neden olduğuna bakmalıyım).

GHC'nin kendisinin bir kütüphane olduğunu unutmayın , bu nedenle 4 adet GHC kopyası alıyorsunuz. Sadece bu da değil, GHC ikilisinin kendisi statik olarak bağlantılıdır, yani bu 5 GHC kopyasıdır.

Yakın zamanda GHCi'nin statik .adosyaları kullanabilmesi için yaptık . Bu, bu tatlardan birinden kurtulmamızı sağlayacaktır. Daha uzun vadede, GHC'yi dinamik olarak bağlamalıyız, ancak bu daha büyük bir değişiklik çünkü bu, dinamik bağlamayı varsayılan olarak yapmayı gerektirecek - C'den farklı olarak, GHC ile dinamik olarak bağlanıp bağlanmayacağınıza önceden karar vermelisiniz. Ve bu gerçekten pratik olmadan önce daha fazla değişikliğe ihtiyacımız var (örneğin, Cabal ve diğer şeylerin yanı sıra paket sistemde).


16
Ve burada Haskell'in sunduğu tüm mantığın bu olduğunu düşündüm: tembel değerlendirme, tür çıkarımı, vb.
mcandre

4
Yani, 113MB / 4 ~ = 28MB, yine de OpenJRE'den daha büyük ... Ancak GHC'nin OpenJDK ile karşılaştırılabilir olduğunu düşünün, sadece JRE ile değil, beni daha iyi hissettiriyor.
Earth Engine

1
Şimdi, GHC'nin dinamik bağlantı kullandığını düşünüyorum, belki de Dr. @ Simon Marlow'un dört çeşidin sıkıştırılmasına ilişkin fikirleri daha pratik olabilir mi? Alıntılar: 1. # 3658 ( GHCi'yi destekleyen platformlara dinamik olarak bağlayın (ve sistem bağlayıcıyı kullanın) - GHC ghc.haskell.org/trac/ghc/ticket/3658 ; 2. # 8266 (Mac'te Dinamik bağlantı) - GHC ghc.haskell.org/trac/ghc/ticket/8266 ; 3. # 8376 (Static Executable + GHC API (+ Dynamic Linking?) Segfault verir) - GHC
AnneTheAgile

56

Muhtemelen elmaları elmalarla ve portakalları portakallarla karşılaştırmalıyız. JRE, bir geliştirici kiti değil, çalışma zamanıdır. Aşağıdakileri karşılaştırabiliriz: geliştirme kitinin kaynak boyutu, derlenmiş geliştirme kitinin boyutu ve minimum çalışma süresinin derlenmiş boyutu.

OpenJDK 7 kaynak paketi 82 MB (download.java.net/openjdk/jdk7) ve 23 MB olan GHC 7 kaynak paketi (haskell.org/ghc/download_ghc_7_0_1). GHC burada büyük değil. Çalışma zamanı boyutu: Ubuntu'da openjdk-6-jre-headless 77 MB sıkıştırılmamış, Haskell helloworld'e kıyasla <1 MB olan çalışma zamanıyla statik olarak bağlantılı. GHC burada büyük değil.

GHC'nin büyük olduğu yerde, derlenen geliştirme kitinin boyutu:

GHC disk kullanımı

GHC'nin kendisi 270 MB alır ve bir araya gelen tüm kütüphaneler ve yardımcı programlarla birlikte 500 MB'nin üzerinde yer kaplar. Ve evet, temel kitaplıklar ve bir oluşturma aracı / bağımlılık yöneticisi ile bile çok fazla. Java geliştirme platformu daha küçüktür.

GHC:

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

OpenJDK bağımlılıklarına karşı:

$ 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

Ama yine de 100 MB'den fazla, yazarken 26 MB değil.

Ghc6 ve ghc6-prof'deki ağır şeyler şunlardır:

$ 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

Lütfen ne kadar büyük olduğuna dikkat edin libHSghc-6.12.1_p.a. Dolayısıyla yanıt, her kitaplık için statik bağlama ve profil oluşturma sürümleri gibi görünüyor.


9

Benim tahminim - çok ve çok fazla statik bağlantı. Her kitaplığın bağımlılıklarını statik olarak birbirine bağlaması gerekir, bu da kendi bağımlılıklarını statik olarak birbirine bağlamalıdır. Ve bunların tümü genellikle hem profil oluşturma ile hem de profilleme olmadan derlenir ve hatta profil oluşturmadan bile ikili dosyalar çıkarılmaz ve bu nedenle çok sayıda hata ayıklayıcı bilgisi tutar.


2
GHC'nin tam bir programa geçmesi, jhc'ye benzer şekilde hemen hemen her şeyi yeniden derlemesinin bir sakıncası yoktur. Hatta "ld" nin değişmesini önleyecekse daha hızlı derlenebilir.
John L

8

Çünkü gcc ve bir grup kütüphaneyi bir araya getirdiği için hepsi statik olarak bağlantılı.

En azından Windows'ta.


12
hayır, linux üzerinde değil. yalnızca gcc'ye bağlıdır. pencerelerin "dağıtımında" gcc bulunmadığından, ghc ile gelmek zorundadır.
comonad

5

Kutumdaki dizin boyutu dökümü:

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

Görünüşe göre en büyük dizin (123 MB), derleyicinin kendisini derlemek için kullanılan ikili dosyalar. Belgeler şaşırtıcı bir 65 MB ağırlığındadır. Üçüncülük 41 MB ile Cabal.

Bin dizini 33 MB'dir ve Haskell uygulamalarını oluşturmak için teknik olarak gerekli olan şeyin yalnızca bir alt kümesidir.


6
Buna bir şey ekleyeyim: Yalnızca barebone derleyiciyi alır ve kesinlikle gerekli olmayan herhangi bir şeyi çıkarırsanız (derleyiciyi profilsiz, soyulmuş vb. Oluşturmak gibi), yaklaşık 5 MB'ye inebilirsiniz. Ancak derleyicilerin boyutunu GCC ile karşılaştırmaya çalışın. (Yorumu
düzenledim

5

Kısa cevap, tüm çalıştırılabilir dosyalar statik olarak bağlantılı olduğundan, içlerinde hata ayıklama bilgilerine sahip olabileceğinden ve kitaplıkların birden çok kopyaya dahil edilmesidir. Bu zaten diğer yorumcular tarafından söylendi.

Dinamik bağlantı mümkündür ve boyutu önemli ölçüde azaltır. İşte bir örnek Hello.hs:

main = putStrLn "Hello world"

Windows üzerinde GHC 7.4.2 ile oluşturuyorum.

ghc --make -O2Hello.exe1105 bin verir

Koşu stripÜzerinde 630K bırakır

ghc --make -O2 -dynamic 40 bin verir

Sıyrıldığında geriye sadece 13K kaldı.

Bağımlılıkları, toplam boyutu 9,2 MB şeritlenmemiş ve 5,7 MB çıkarılmış 5 dll'dir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.