LINUX.ORG.RU

Встраиваемые языки: lua, python, scheme, etc?

 , , ,


0

3

Добрый вечер, обитатели цифрового моря.
Буду краток. Имеется большой монолит, написанный на сpp, к которому понадобилось прикрутить систему плагинов и конфигурации. Собственно, ищется язык-кандидат на роль для встраивания в нашего франкенштейна. Требование к кандидату только одно - скорость.

Я уже пытался читать архивные топики на эту тему, но ничего особо полезного не вынес, так как обычно все скатывалось в обсуждение того, кто является бОльшим хипстером или в лицензесрачи, которые вообще не относились к теме топика.

Хотелось бы услышать ваш личный личный опыт по данному вопросу и узнать о возможных подводных камнях.


Требование к кандидату только одно - скорость.

Если скорость работы (а не скорость запуска) то самым подходящим будет всё тот же cpp, на лету компилируемый в .so перед запуском (с помощью gcc или может tcc - он быстрее).

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)

а вот смотря как ваш монолит устроен, что он делает и чего хочет от скриптов.

вообще вариантов всего 3 : tcl, lua, mruby ; Они для подобного и придуманы в разное время.

у остальных есть большие проблемы с GIL, GC, тредами, изоляций отдельных модулей (чтобы один плагин не мог сильно нагадить другому), толстотой объектов, наличием библиотек и даже инициализацией

MKuznetsov ★★★★★
()
Ответ на: комментарий от firkax

Если честно, то как-то не очень удобно каждый раз перекомпилировать, да и чего уж там, на плюсах писать уже устали, хочется заморозить «ядро» и больше не прикасаться к нему. Плюс софтина может эксплуатироваться на системах, где возможно и не будет необходимого тулчейна. В этом плане можно пожертвовать скоростью работы взамен на расширяемость, но не сильно)

eyrell
() автор топика
Ответ на: комментарий от eyrell

Если честно, то как-то не очень удобно каждый раз перекомпилировать

Я имел ввиду что перекомпилировать (и сразу dlopen()) будет сама прога, которая грузит плагин, а снаружи это будет обычный исходник.

на системах, где возможно и не будет необходимого тулчейна

Ну, интерпретатор питона или луа с собой таскать можно а си-компилятор нельзя? Посмотри на tcc https://bellard.org/tcc/ он вполне легковесный и его можно даже ембедить в свой бинарник вместо вызова отдельным процессом.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 2)
Ответ на: комментарий от MKuznetsov

Основное предназначение - дергать одни вызовы из монолита, проводить некоторые манипуляции с данными и дергать другие вызовы из монолита, чтобы эти данные отдать.

eyrell
() автор топика
Ответ на: комментарий от firkax
    Компактность. Исполняемый файл для процессоров x86, включающий препроцессор, компилятор, ассемблер и компоновщик, составляет всего около 100 КБ.[5]
    Высокая скорость компиляции. Например, TCC примерно в 9 раз быстрее GCC.[6]
    Возможность формировать код с контролем границ массивов, который можно беспрепятственно использовать вместе с обычным кодом.
    Возможность напрямую использовать любую динамическую библиотеку.
firkax ★★★★★
()

ваш личный личный опыт

Наш личный тебе «ни к селу, ни к городу». Исхори из архитектуры своего проекта. Если у тебя ядро на c++ то и плагины пиши на нем же, как уже написали выше, подргужай их через dlopen. Исходя из поверхностно описанного тобой ТЗ, это наиболее оптимальное решение.

iron ★★★★★
()

Требование к кандидату только одно - скорость.

Таких требований достаточно только для срача, но не для серьёзной дискуссии.

  • Скорость или латентность? Другими словами: один и тот же код выполняется по многу раз, или всё время меняется?
  • На каких задачах? Важна ли производительность вычислений? С плавающей точкой? А если это какие-то простенькие скрипты с бизнес-логикой, то возникает вопрос, на хрена там нужна скорость.
  • Есть ли возможность использовать JIT на целевой платформе? Допустимо ли тратить на JIT ресурсы (память, проц)?
  • Кто будет писать эти скрипты? Какая у них квалификация и предпочтения?
  • Должен ли ЯП быть интерпретируемым, или допустима какая-то предварительная компиляция?
annulen ★★★★★
()
Ответ на: комментарий от eyrell

Основное предназначение - дергать одни вызовы из монолита, проводить некоторые манипуляции с данными и дергать другие вызовы из монолита, чтобы эти данные отдать.

Похоже что скорость тут чисто для галочки, а производительность вычислений не важна. Я бы взял LuaJIT, а включать ли в нём JIT или нет — на ваше усмотрение.

annulen ★★★★★
()
Ответ на: комментарий от annulen

Да, я уже понял, что не очень ясно выразился.
Так как решение перейти на скриптовый язык уже было принято, то имелась ввиду скорость «интерпретации кода»(назовем это так, в тематической терминологии, простите, не силен) именно среди скриптовых встраивамых языков.

Вообще хорошим решением было бы разложить монолит на библиотеки и дергать их из скриптового языка, как это делают нормальные люди, но с данным проектов, увы, так не получится.

eyrell
() автор топика
Ответ на: комментарий от eyrell

Если смотреть на скорость интерпретации без каких-либо JIT’ов, то LuaJIT. У него кстати платформенно-независимый формат байткода, так что можно делать «предкомпиляцию», если хочется.

У JavaScriptCore (и, наверное, V8) со скоростью чистой интерпретации тоже всё хорошо, но они намного больше по размеру. И никакого портабельного байткода. Зато более попсовый ЯП.

annulen ★★★★★
()
Ответ на: комментарий от eyrell

Мне кажется, что в вашем случае по скорости выполнения все варианты будут примерно одинаковы (особенно если скриптового кода будет не слишком много).

Отличия могут быть в скорости доступа к нативным данным. Например, если скрипты будут часто доставать из нативного кода строки, то в случае с браузерными JS-движками их придётся все время конвертировать в строковый тип JS-движка. А у интепретаторов, специально заточенных под встраивание (для JS такие тоже есть), таких проблем быть не должно.

annulen ★★★★★
()
Ответ на: комментарий от eyrell

Вполне возможно, что в вашем случае скорость вообще последний фактор, на который надо смотреть, а реальное значение имеют такие факторы как простота интеграции с нативным кодом, требования и квалификация пользователей, потребность/возможность использования сторонних библиотек для этого ЯП в скриптах (и их наличие).

annulen ★★★★★
()

Я понимаю ваше негодование, но я сам нахожусь в полной растерянности и не совсем понимаю, что мне нужно делать. Начнем с того, что по профессии я не совсем программист, но по воле судьбы мне удалось попасть в одну местечковую компанию, которая работает с европейскими рынками. И насколько мне известно, этот самый монолит был написан в бородатые времена европейскими партнерами и который, совершенно недавно, они захотели переписать с нуля, чтобы адаптировать его под современные реалии. Но видимо что-то пошло не так и этот проект решили спихнуть на аутсорс Восточной Европе. По итогу этот монолит с некоторым перечнем требований попал ко мне, вчерашнему студенту, и к таким же бедолагам как я. Думаю, стоит упомянуть, что монолит был написан какими-то работниками европейского НИИ на лапше в стиле «Си с классами» и который вообще не имеет какой либо вменяемой архитектуры. Но нам удалось переписать некоторые его части, подготовить API и собрать стабильную версию монолита, которая не падает при работе. Вот на этом моменте мы хотим остановиться, перейти на скиптовый язык и больше никогда не прикасаться к этому куску г…кода.
Все ресурсоемкие операции уже находятся в монолите и посредством скриптов выполняться не будут, поэтому с требованием «скорость» я, скорее всего, ошибся. А все остальные задачи(почти все) не будут выходить за рамки обычного перекладывания байтов из одного места в другое и вызова c API.

eyrell
() автор топика
Ответ на: комментарий от annulen

Например, если скрипты будут часто доставать из нативного кода строки, то в случае с браузерными JS-движками их придётся все время конвертировать в строковый тип JS-движка. А у интепретаторов, специально заточенных под встраивание (для JS такие тоже есть), таких проблем быть не должно.

Щито?

Во-первых, «конвертировать» означает прежде всего скопировать строку из текущей памяти в рантайм языка. Т.е. строка может потом исчезнуть из памяти, а значение-строка должно жить, пока её не соберёт GC. Основные расходы «конвертировать» — именно на копирование и динамическое выделение памяти.

Во-вторых, JavaScript требует UTF-16 на уровне спецификации языка, а в C или C++ на онтопике строки чаще всего будут в UTF-8. Если в строке только ASCII, её можно хранить как UTF-8 и делать вид, что там UTF-16. Если в строке есть не-ASCII, то в общем случае это не работает и ты обязан хранить UTF-16.

В-третьих, в V8 как раз есть куча оптимизаций для строк: https://github.com/danbev/learning-v8/blob/master/notes/string.md В том числе ExternalString и ExternalInternalizedString, которые могут быть как UTF-8, так и UTF-16. В то время как во встраиваемых движках (MuJS, QuickJS) таких вещей нету, там ты обязан копировать строки.

cudeta
()

Python встроить можно, но это дикое извращение. Нормальное решение когда срр модуль импортится в питон.

Так народ вроде луа встраивает.

AntonI ★★★★
()
Ответ на: комментарий от eyrell

Вот на этом моменте мы хотим остановиться, перейти на скиптовый язык и больше никогда не прикасаться к этому куску г…кода.

Кто будет писать плагины? Только твоя команда? Тогда оцени компетенции и возьми язык, с которым комфортно себя чувствует больше членов команды. Если конечные потребители - дай им wasm и пусть пишут хоть на лиспе, если им так угодно.

si0 ★★★
()
Ответ на: комментарий от eyrell

чтобы остальные члены команды меня не побили за JS

Во-первых можно транслировать много чего в js. Во-вторых там есть wasm что ещё более расширяет набор языков. В-третьих JS это само по себе замечательно, потому что легче найти негров которые будут писать тебе модули/конфиги. В-четвёртых, дофига всяких батареек и развитый тулчейн. Со всех сторон это минимум геморроя и максимум профита.

Не слушай клоунов которые тебе советуют всякое говно мамонта вроде lua, или тем более tcl. Это вчерашний день.

no-such-file ★★★★★
()

Требование к кандидату только одно - скорость. Хотелось бы услышать ваш личный опыт по данному вопросу и узнать о возможных подводных камнях.

Делал свой собственный простенький интерпретатор для общего развития на C++. Сравнивал по скорости с Питоном на вычислениях простых функций типа факториала и чисел Фибоначчи. Изначально Питон был примерно в 240 раз быстрее. После оптимизаций мой интерпретатор обогнал Питон примерно в три раза. Правда, я не делал проверки на переполнение, деление на ноль и т.д. Так что можно сказать, что скорости примерно сравнялись.

Это я к тому, что если операции относительно простые - то любой интерпретатор даст хорошую скорость. Проблемы могут быть когда начнём применять ООП, потоки, когда заработает сборщик мусора. Пока не ясно, нужно ли всё это в данной теме.

Кроме того, самописные интерпретаторы могут прямо использовать типы C++. Так что не придётся ничего преобразовывать и копировать.

Kogrom
()
Ответ на: комментарий от eyrell

По итогу этот монолит с некоторым перечнем требований попал ко мне, вчерашнему студенту, и к таким же бедолагам как я

<…>

Вот на этом моменте мы хотим остановиться, перейти на скиптовый язык и больше никогда не прикасаться к этому куску г…кода.

Тогда бери Python, не ошибёшься

  • Так как планируется использовать скрипты в качестве основного средства разработки, то понадобятся «батарейки», которых у Python гораздо больше, чем у других ЯП, обсуждаемых в треде
  • Для начинающих Python подходит лучше, чем JS
  • При этом найти готового питониста легче, чем человека со знанием Lua или Scheme. Когда мне попадались вакансии с Lua, там всегда писали «опыт не обязателен, научим по ходу»
annulen ★★★★★
()
Ответ на: комментарий от NorthernBlow

накидайте-ка ему клоунов ребята

Сам ты клоун. Если пацаны привыкли к шарпу/java - TS вас спасёт. Node - хороша. Скорость и батарейки на любой чих. Годное API для своих батареек: https://nodejs.org/api/addons.html#node-api и всё модно-молодёжно. Второй плюс - хайпец. Разберётесь и будете нужны на рынке.

А ты просто тупой лось.

anonymous
()
Ответ на: комментарий от firkax

Ну, интерпретатор питона или луа с собой таскать можно а си-компилятор нельзя?

конечно можно. только разница в том, что интерпретатор своей спиной прикроет всю кривоту компилируемого кода и твоя софтина будет спать спокойно. с сишным компилятором - чуть не то сделает «гость» твоей софтины и ОС убьет не глядя, не разбираясь кто там виноват.

ergo ★★★
()
Последнее исправление: ergo (всего исправлений: 1)
Ответ на: комментарий от annulen

Питон как встраиваемое решение имеет два серьёзных недостатка:

  1. он толстый

  2. у него совершенно уродский C API

Все эти танцы с бубном вокруг PyObject* омерзительны.

AntonI ★★★★
()
Ответ на: комментарий от AntonI

Есть Boost.Python и другие способы не взаимодействовать с C API. А «толстый» — скорее преимущество, если предполагается использовать его как основное средство разработки.

annulen ★★★★★
()
Ответ на: комментарий от annulen

Не знаю… мб конечно ТС-у питон оптимально подходит, но у мну внутри все протестует против такого его использования:-)

Такая архитектура оскорбляет тык-скыть моё чувство прекрасного.

AntonI ★★★★
()
Ответ на: комментарий от firkax

Какого движка?

Можешь назвать это

Имеется большой монолит, написанный на сpp, к которому понадобилось прикрутить систему плагинов и конфигурации.

по-другому, но по факту это «движок», как в какой-нибудь игре.

Virtuos86 ★★★★★
()
Ответ на: комментарий от firkax

Высокая скорость компиляции. Например, TCC примерно в 9 раз быстрее GCC.[6]

Девушка устраивается на работу в офис:

  • Печатаю со скоростью 1200 знаков в минуту. Все ахают. Она потихоньку в сторону:
  • Такая фигня получается.
Siborgium ★★★★★
()
Ответ на: комментарий от Siborgium

Сравнение неуместно, tcc всё компилирует правильно. В том числе был даже загрузчик Linux-ядра из исходников с компиляцией на лету с помощью него.

firkax ★★★★★
()