Є проста відповідь: Чому GHC настільки великий?
- OCaml: 2 Мб
- Пітон: 15 Мб
- SBCL: 9 Мб
- OpenJRE - 26 Мб
- GHC: 113 Мб
Не цікавиться євангелізацією "Чому я не повинен дбати про розмір, якщо Haskell - це правильний інструмент"; це технічне питання.
Є проста відповідь: Чому GHC настільки великий?
Не цікавиться євангелізацією "Чому я не повинен дбати про розмір, якщо Haskell - це правильний інструмент"; це технічне питання.
Відповіді:
Це справді трохи нерозумно. Кожна бібліотека, що постачається з GHC, надається не менше ніж у 4 смаках :
Версія GHCi - це лише статична версія, пов'язана разом в одному .o
файлі. У всіх трьох інших версіях також є свій набір файлів інтерфейсу ( .hi
файлів). Профільовані версії, схоже, приблизно вдвічі перевищують непрофільовані версії (що трохи підозріло, я мушу розглянути, чому це так).
Пам'ятайте, що GHC сама по собі є бібліотекою , тому ви отримуєте 4 копії GHC. Не тільки це, але і сам бінарний GHC є статично пов'язаним, так що це 5 копій GHC.
Нещодавно ми зробили це, щоб GHCi могли використовувати статичні .a
файли. Це дозволить нам позбутися одного з цих ароматів. Більш тривалий термін, ми повинні динамічно пов'язувати GHC, але це більша зміна, оскільки це спричинить динамічне пов'язування за замовчуванням - на відміну від C, з GHC ви повинні вирішити попереду, чи будете ви динамічно зв’язуватися чи ні. І нам потрібно більше змін (наприклад, до Кабалу та пакетної системи, серед іншого), перш ніж це буде реально практичним.
Напевно, нам слід порівняти яблука з яблуками, а апельсини - з апельсинами. JRE - це час виконання, а не комплект розробників. Ми можемо порівняти: розмір джерела набору для розробки, розмір складеного набору розробок та розмір складеного мінімального часу виконання.
Вихідний пакет OpenJDK 7 становить 82 Мб (download.java.net/openjdk/jdk7) проти вихідного пакета GHC 7, що становить 23 Мб (haskell.org/ghc/download_ghc_7_0_1). GHC тут не великий. Розмір часу: openjdk-6-jre-headless на Ubuntu становить 77 Мб, нестиснений проти Haskell helloworld, статично пов'язаний з його часом виконання, який становить <1 Мб. GHC тут не великий.
Там, де GHC великий, - це розмір складеного набору для розробки:
Сам GHC займає 270 МБ, а з усіма бібліотеками та утилітами, які поєднуються, він займає понад 500 Мб. І так, це багато, навіть з базовими бібліотеками та інструментом збирання / менеджера залежностей. Платформа для розробки Java менша.
GHC:
$ aptitude show ghc6 | grep Size
Uncompressed Size: 388M
проти OpenJDK із залежностями:
$ 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 Мб, а не 26 Мб, як ви пишете.
Важкі речі у 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=uk
Схоже, найбільший каталог (123 МБ) - це двійкові файли для компіляції самого компілятора. Документи важать вражаючі 65 МБ. Третє місце - Кабал у 41 МБ.
Каталог бін становить 33 Мб, і я думаю, що для створення програм Haskell технічно потрібно лише підмножина.
Коротка відповідь полягає в тому, що всі виконувані файли статично пов'язані, можливо, в них є інформація про налагодження, і бібліотеки включаються в декількох копіях. Про це вже говорили інші коментатори.
Можливе динамічне зв’язування та значно зменшить розмір. Ось приклад Hello.hs
:
main = putStrLn "Hello world"
Я будую з GHC 7.4.2 на Windows.
ghc --make -O2
дає Hello.exe
1105Ks
Біг strip
на ньому залишає 630K
ghc --make -O2 -dynamic
дає 40К
Знімаючи його, залишається всього 13К.
Її залежності - це 5 dll загальним розміром 9,2 Мб, роздягнуті та 5,7 Мб.