Создание небольших исполняемых файлов Haskell?
-
22-08-2019 - |
Вопрос
Есть ли хорошие способы создания небольших исполняемых файлов Haskell?С ghc6 простая программа hello world занимает около 370 КБ (523 КБ до удаления).Привет, мир в C занимает около 4 КБ (9 КБ до полосы).
Решение
С веткой разработки GHC (кто-нибудь точно знает, в какой версии это было добавлено?):
$ ghc -o hello hello.hs
$ strip -p --strip-unneeded --remove-section=.comment -o hello-small hello
$ du hello hello-small
700 hello
476 hello-small
Добавьте флаг -dynamic для динамически связанной RTS:
$ ghc -dynamic -o hello hello.hs
$ strip -p --strip-unneeded --remove-section=.comment -o hello-small hello
$ du hello hello-small
24 hello
16 hello-small
Смотрите также: http://hackage.haskell.org/trac/ghc/wiki/SharedLibraries/PlatformSupport
Для сравнения с С:
$ gcc hello.c -o hello
$ strip -p --strip-unneeded --remove-section=.comment -o hello-small hello
$ du hello hello-small
12 hello
8 hello-small
Другие советы
GHC статически связывает все (кроме библиотек, используемых самой средой выполнения, которые подключаются динамически).
Раньше GHC связывал всю библиотеку (haskell) сразу после того, как вы что-то из нее использовали.Некоторое время назад GHC начал компоновать «на каждый obj-файл», что резко уменьшило размер двоичного файла.Судя по размеру, вы, должно быть, уже использовали более новый GHC.
С другой стороны, в этих 500 КБ уже есть много всего, например, многопоточное ядро, сборщик мусора и т. д.
Добавьте хотя бы сборщик мусора в свой код C, а затем сравните их еще раз :)
Размер, который вы видите, — это среда выполнения Haskell (libHSrts.a), которая статически связана с каждым исполняемым файлом Haskell.Если бы это был общий объект, например librt.o для C, размер вашего двоичного файла был бы всего несколько k (размер разделенного файла .o в исходном коде библиотеки).
Если не использовать динамическое связывание libHSrts.a на вашей платформе, вы можете уменьшить размер своих исполняемых файлов с помощью Strip.
Если размер вашего двоичного файла действительно имеет значение, вы можете использовать инструмент gzexe который упаковывает (желательно уже удаленный) исполняемый файл со сжатием gzip.На моем 64-битном компьютере с Linux оригинал Привет, мир программа занимает 552 КБ, после зачистки 393 КБ, а после зачистки и сжатия 125 КБ.Темная сторона gzip-сжатия заключается в производительности: сначала необходимо распаковать исполняемый файл.
Вам пора считать свои блага (370Кб?Роскошь) :
bash$ sbcl This is SBCL 1.0.24, an implementation of ANSI Common Lisp. * (sb-ext:save-lisp-and-die "my.core") [undoing binding stack and other enclosing state... done] [saving current Lisp image into ./my.core: ... done] bash$ du -sh my.core 25M my.core bash$
А если серьезно, хотя вы, вероятно, и можете немного встряхнуть двоичные файлы Haskell, на самом деле это некорректное сравнение с C.Там происходит нечто большее.
В прошлый раз, когда я играл с ghc (и это могло быть устарело), он все связывал статически, что будет иметь значение.
Ситуация меняется – следите за новостями этот продолжающаяся часть работы.
strip -p --strip-unneeded --remove-section=.comment -o your_executable_small your_executable
также попробуйте посмотреть ldd -dr your_executable