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.
Basit bir cevap var mı: GHC neden bu kadar büyük?
"Haskell doğru araçsa boyutu neden umursamamalıyım" evanjelizmiyle ilgilenmiyorum; bu teknik bir sorudur.
Yanıtlar:
Gerçekten biraz aptalca. GHC ile birlikte gelen her kitaplık en az 4 çeşitte sağlanır :
GHCi sürümü, tek bir .o
dosyada birbirine bağlanmış statik sürümdür . Diğer üç sürümün de kendi arabirim dosyaları ( .hi
dosyaları) 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 .a
dosyaları 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).
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'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.
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.
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.
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 -O2
Hello.exe
1105 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.