[C, C++, Программирование, Функциональное программирование] Сравнение встраиваемых ЯП по размеру в исполняемом файле

Автор Сообщение
news_bot ®

Стаж: 6 лет 9 месяцев
Сообщений: 27286

Создавать темы news_bot ® написал(а)
20-Окт-2020 00:31

В рамках одного из моих SDK-проектов нам понадобилось добавить скриптование, которое бы оказало наименьший эффект на размер конечного бинарного файла, но при этом предоставляло хорошую фунциональность. Это дало старт проекту, который описан в этой статье. Прошу заметить, что т.к. в SDK у нас есть определенные требования, они частично перенеслись на язык скриптования, поэтому в проекте не участвовали некоторые достаточно известные встраиваемые ЯП (но Lua включен для сравнения).
Сайт проекта доступен по ссылке https://gitlab.com/nuald-grp/embedded-langs-footprint Скажу сразу, что на данный момент для меня лично победителем является Chibi-Scheme. Подробности для заинтересовавшихся под катом.
Требования были следующие:
  • Максимальная переносимость (только C/C++).
  • Достаточно строгая типизация (не позволяющая складывать апельсины с яблоками), соответственно реализации ECMAScript не рассматривались.
  • Удобство минимизации самих скриптов (например, чтобы можно было безопасно удалить все переносы строк), соответственно реализации Forth, Lua и Python не рассматривались.
  • Лицензия, дружелюбная к коммерческим проектам.

Изначальный список был взят с проекта, в котором они пытаются учесть все возможные встраиваемые ЯП: https://github.com/dbohdan/embedded-scripting-languages Возможно, список не полный, и не содержит дополнительные ЯП, которые могли бы удовлетворять вышеуказанным требованиям. Если вы знаете о таких, пожалуйста, дайте мне знать либо в личку, либо комментарием.
Тестовый код для всех ЯП включал в себя создание и вызов функции, которая складывает "Hello, " и результат вызова внешней (C/C++) функции, возвращающей "world". Код функции представлен в таблице как образец синтаксиса. Конечный исполняемый файл скомпилирован с оптимизацией по размеру и с удалением всех ненужных символов (GCC -s).
Также должен отметить, что хотя изначальный список был достаточно большой, в итоге вышеуказанным требованиям удовлетворили всего 8 ЯП (Lua в списке только для сравнения):
ЯП
Размер (байты)
Пример скрипта
TinyScheme
86824
(define fn(lambda () (string-append "Hello, " (read))))
Lua
252880
function fn() return "Hello, " .. read() end
Chibi-Scheme
261480
(define fn(lambda () (string-append "Hello, " (read))))
Squirrel
277008
function fn() { return "Hello, " + read(); }
ArkScript
449792
(let fn(fun() (+ "Hello, " (read))))
Gravity
507896
extern var read; func fn() { return "Hello, " + read(); }
Janet
537560
(defn fn[] (string "Hello, " (read)))
ChaiScript
1374976
def fn() { return "Hello, " + read(); }
AngelScript
1923960
string fn() { return 'Hello, ' + read(); }
Описание и документация по этим ЯП приведены в GitLab-проекте, здесь же хочу поделиться своими впечатлениями:
  • ChaiScript очень интересный — наверное самой простой по удобству встраивания, плюс поддерживается крупными компаниями. К сожалению, тот факт, что он состоит только из заголовочных файлов, очень сильно замедляет компиляцию (мой Dell XPS 13 компилирует минимум 2-3 минуты). Также, он достаточно сильно увеличивает размер исполняемого файла.
  • Gravity может понравится любителям Swift. Достаточно интересный ЯП, но к сожалению, не так много документации. Ориентирован на мобильную разработку.
  • Squirrel достаточно компактный, но достаточно сложно встраивать (любая ошибка в работе со стеком вызовов приводит к краху приложения — у них недостаточно хорошая система обработки ошибок).

Chibi-Scheme стал победителем, т.к. поддерживает современный компактный Scheme (R7RS) и имеет достаточно большую дополнительную библиотеку (плюс стандартная библиотека Scheme и возможность использовать уже написанный код). Естественно, встраивание библиотек увеличит конечный код, но даже без библиотек он может полноценно работать (тестовый код не встраивал init-7.scm полностью, а только добавил процедуру string-append).
Встраивание внешних процедур достаточно простое (хотя я вставил лямбду, Chibi-Scheme полноценно работает с чистым C):
res = sexp_define_foreign(*ctx, sexp_context_env(*ctx), "read", 0,
                          [](sexp ctx, sexp self, sexp_sint_t n) -> sexp {
                            return sexp_c_string(ctx, "world", -1);
                          });

Из интересных дополнительных модулей хотел бы отметить:

К сожалению, документация не богатая, но компенсируется доступом ко всему исходному коду. Плюс, Chibi-Scheme известен в своих кругах, и не будет потенциально брошен или переведен в режим минимальной поддержки, как некоторые другие потенциальные кандидаты.
Буду рад услышать все комментарии, и рассмотреть другие ЯП в рамках вышеупомянутых требований. Исследование до сих продолжается, и возможно победитель сменится, но это уже будет зависеть от вас.
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_c, #_c++, #_programmirovanie (Программирование), #_funktsionalnoe_programmirovanie (Функциональное программирование), #_c, #_c++, #_scheme, #_lua, #_tinyscheme, #_chibischeme, #_squirrel, #_arkscript, #_gravity, #_janet, #_chaiscript, #_angelscript, #_c, #_c++, #_programmirovanie (
Программирование
)
, #_funktsionalnoe_programmirovanie (
Функциональное программирование
)
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 22-Ноя 19:43
Часовой пояс: UTC + 5