Ваш вопрос очень широкий, и я не уверен, что он соответствует формату Stackoverflow.Это заслуживает тщательного обсуждения .
Размер 190 КБ - это слишком много для простой программы, такой как в современных ограничениях (iot, android, alpine VM ...), и плохо сравнивается с простой программой на C (около ~ 6 КБ,или непосредственно кодируя ASM и настраивая вещи, чтобы получить работающий двоичный файл, который может быть около 150B)
Прежде всего, это не честное сравнение.В настоящее время скомпилированный двоичный файл C является артефактом, который далек от того, чтобы быть автономным двоичным файлом.Это должно быть больше похоже на плагин в рамках.Поэтому, если вы хотите подсчитать, сколько байтов фактически использует данный двоичный файл, мы посчитаем размер загрузчика, оболочки, библиотеки libc и всего ядра Linux или Windows - которые в совокупности образуют среду выполнения приложения.
OCaml, в отличие от Java или Common Lisp, очень дружественен к обычной среде выполнения C и пытается использовать большинство своих возможностей.Но OCaml все еще имеет собственную среду выполнения, в которой самая большая (и самая важная часть) - сборщик мусора.Время выполнения не очень большое (около 30 KLOC), но все же способствует увеличению веса.А поскольку OCaml использует статическое связывание, каждая программа OCaml будет иметь его копию.
Следовательно, двоичные файлы C имеют существенное преимущество, поскольку они обычно запускаются в системах, где среда выполнения C уже доступна (поэтому она обычно исключается из уравнения).Однако существуют системы, в которых время выполнения C вообще отсутствует, и присутствует только время выполнения OCaml, см., Например, Mirage .В таких системах двоичные файлы OCaml гораздо более выгодны.Другим примером является проект OCaPic , в котором (после настройки компилятора и среды выполнения) им удалось приспособить среду выполнения OCaml и программы к 64 КБ Flash (см. Статью , очень проницательно одвоичные размеры).
Как получить наименьший двоичный файл из ocamlopt?
Когда действительно необходимо минимизировать размер, используйте Mirage Unikernels или реализуйте свою собственную среду выполнения.Для общих случаев используйте strip
и upx
.(Например, с upx --best
я смог уменьшить двоичный размер вашего примера до 50К, без каких-либо дополнительных хитростей).Если производительность не имеет большого значения, вы можете использовать байт-код, который обычно меньше машинного кода.Таким образом, вы заплатите один раз (около 200 тыс. За время выполнения) и несколько байтов для каждой программы (например, 200 байт для вашего helloworld).
Кроме того, не создавайте много маленьких двоичных файлов, но создайте один двоичный файл.В вашем конкретном примере размер модуля компиляции helloworld составляет 200 байтов в байт-коде и 700 байтов в машинном коде.Остальные 50 КБ - это стартовый жгут, который должен быть включен только один раз.Более того, поскольку OCaml поддерживает динамическое связывание во время выполнения, вы можете легко создать загрузчик, который будет загружать модули при необходимости.И в этом случае двоичные файлы станут очень маленькими (сотни байтов).
Как будто то, что ocamlopt называет «нативной компиляцией», касается упаковки ocamlrun и не родного байт-кода вашей программы.в одном файле и сделать его исполняемым.Не совсем то, что я ожидал.Я явно пропустил какой-то важный момент.Но если это так, мне будет интересно, почему это не так, как я ожидал.
Нет-нет, это совершенно неправильно.Собственная компиляция - это когда программа компилируется в машинный код, будь то x86, ARM или что-то еще.Среда выполнения написана на C, скомпилирована в машинный код и также связана.Стандартная библиотека OCaml написана в основном на OCaml, также скомпилирована в машинный код и также связана с двоичным файлом (только те модули, которые используются, статическое связывание OCaml очень эффективно при условии, что программа разбита на модули (модули компиляции)довольно хорошо).
Что касается переменной среды OCAMLRUNPARAM
, то это просто переменная среды, которая параметризует поведение среды выполнения, в основном это параметры сборщика мусора.