Lua vs Embedded Lisp и потенциальных других кандидатов. для обработки данных на основе набора
Текущий выбор: lua-jit. Впечатляющие тесты, я привык к синтаксису. Написание высокопроизводительного ABI потребует тщательного рассмотрения того, как я буду структурировать свой С++.
Другие интересующие вопросы
Фон
Я работаю над системой обработки событий большого объема (сложной) в реальном времени. У меня есть DSL, который представляет схему структуры событий в источнике, формат хранения, определенные специфические для конкретного домена конструкции, запуск внутренних событий (для структурирования и обработки общего назначения диска) и кодирование определенных шагов обработки, которые всегда происходят.
DSL выглядит довольно похоже на SQL, infact Я использую berkeley db (через интерфейс sqlite3) для долгосрочного хранения событий. Важная часть здесь заключается в том, что обработка событий выполняется на основе набора, например SQL. Я пришел к выводу, что я не должен добавлять логику обработки общего назначения в DSL, а скорее внедрять lua или lisp, чтобы позаботиться об этом.
В ядре обработки встроен arround boost:: asio, он многопоточен, rpc выполняется через буферы протоколов, события закодированы с использованием библиотеки протокола IO протокола --ie, события не структурированы с использованием объекта буфера протокола, который они используют одна и та же библиотека кодирования/декодирования. Я создам объект набора данных, который содержит строки, очень похожие на то, как хранит механизм базы данных в наборах памяти. этапы обработки в DSL будут рассмотрены сначала, а затем представлены логике обработки общего назначения.
Независимо от того, какая среда встраиваемых скриптов я использую, каждый поток в моем ядре обработки, вероятно, нуждается в его собственной среде embedded-language-среды (так как lua требует, чтобы это было, по крайней мере, если вы выполняете многопоточную работу).
Вопрос (ы)
Выбор в данный момент находится между lisp ECL и lua. Помня о том, что производительность и пропускная способность являются сильным требованием, это означает, что минимальное выделение памяти очень желательно:
-
Если бы вы были в моем положении, какой язык вы бы выбрали?
-
Существуют ли какие-либо альтернативы, которые я должен рассмотреть (не предлагайте языки, которые не имеют внедряемой реализации). Возможно, Javascript v8?
-
Помогает ли lisp соответствовать домену? Я не думаю, что lua и lisp отличаются друг от друга тем, что они предоставляют. Вызовите меня: D
-
Есть ли какие-либо другие свойства (например, ниже), о которых я должен думать?
-
Я утверждаю, что любая форма встроенной базы данных IO (см. пример DSL ниже для контекста) затмевает вызов языка сценариев на порядки, и что выбор или не приведет к увеличению накладных расходов на общую пропускную способность. Я на правильном пути?: D
Желаемые свойства
-
Я хотел бы сопоставить свой набор данных в списке lisp или lua, и я хотел бы свести к минимуму избыточные копии данных. Например, добавление строки из одного набора данных в другой должно пытаться использовать ссылочную семантику, если обе таблицы имеют одинаковую форму.
-
Я могу гарантировать, что набор данных, который передается как вход, не изменится, пока я сделал вызов lua/ lisp. Я хочу, чтобы lua и lisp принудительно не изменяли набор данных, если это было возможно.
-
После завершения встроенного вызова наборы данных должны быть уничтожены, любые созданные ссылки должны быть заменены копиями (я думаю).
Пример DSL
Я присоединяю DSL для удовольствия от просмотра, чтобы вы могли понять, чего я пытаюсь достичь. Примечание. DSL не показывает обработку общего назначения.
// Derived Events : NewSession EndSession
NAMESPACE WebEvents
{
SYMBOLTABLE DomainName(TEXT) AS INT4;
SYMBOLTABLE STPageHitId(GUID) AS INT8;
SYMBOLTABLE UrlPair(TEXT hostname ,TEXT scriptname) AS INT4;
SYMBOLTABLE UserAgent(TEXT UserAgent) AS INT4;
EVENT 3:PageInput
{
//------------------------------------------------------------//
REQUIRED 1:PagehitId GUID
REQUIRED 2:Attribute TEXT;
REQUIRED 3:Value TEXT;
FABRRICATED 4:PagehitIdSymbol INT8;
//------------------------------------------------------------//
PagehitIdSymbol AS PROVIDED(INT8 ph_symbol)
OR Symbolise(PagehitId) USING STPagehitId;
}
// Derived Event : Pagehit
EVENT 2:PageHit
{
//------------------------------------------------------------//
REQUIRED 1:PageHitId GUID;
REQUIRED 2:SessionId GUID;
REQUIRED 3:DateHit DATETIME;
REQUIRED 4:Hostname TEXT;
REQUIRED 5:ScriptName TEXT;
REQUIRED 6:HttpRefererDomain TEXT;
REQUIRED 7:HttpRefererPath TEXT;
REQUIRED 8:HttpRefererQuery TEXT;
REQUIRED 9:RequestMethod TEXT; // or int4
REQUIRED 10:Https BOOL;
REQUIRED 11:Ipv4Client IPV4;
OPTIONAL 12:PageInput EVENT(PageInput)[];
FABRRICATED 13:PagehitIdSymbol INT8;
//------------------------------------------------------------//
PagehitIdSymbol AS PROVIDED(INT8 ph_symbol)
OR Symbolise(PagehitId) USING STPagehitId;
FIRE INTERNAL EVENT PageInput PROVIDE(PageHitIdSymbol);
}
EVENT 1:SessionGeneration
{
//------------------------------------------------------------//
REQUIRED 1:BinarySessionId GUID;
REQUIRED 2:Domain STRING;
REQUIRED 3:MachineId GUID;
REQUIRED 4:DateCreated DATETIME;
REQUIRED 5:Ipv4Client IPV4;
REQUIRED 6:UserAgent STRING;
REQUIRED 7:Pagehit EVENT(pagehit);
FABRICATED 8:DomainId INT4;
FABRICATED 9:PagehitId INT8;
//-------------------------------------------------------------//
DomainId AS SYMBOLISE(domain) USING DomainName;
PagehitId AS SYMBOLISE(pagehit:PagehitId) USING STPagehitId;
FIRE INTERNAL EVENT pagehit PROVIDE (PagehitId);
}
}
Этот проект является компонентом исследовательского проекта Ph.D и является/будет свободным программным обеспечением. Если вы заинтересованы в работе со мной (или вносите вклад) в этот проект, оставьте комментарий: D
Ответы
Ответ 1
Я сильно согласен с точками @jpjacobs. Lua - отличный выбор для встраивания, если вам не что-то очень специфическое в lisp, которое вам нужно (например, если ваши данные особенно хорошо сопоставляются с cons-cells).
Я использовал lisp много лет, BTW, и мне очень нравится синтаксис lisp, но в эти дни я обычно выбирал Lua. Хотя мне нравится язык lisp, мне еще предстоит найти реализацию lisp, которая отражает прекрасный баланс функций/малости/удобства использования для встроенного использования, как это делает Lua.
Lua:
-
Очень маленький, как исходный, так и двоичный, на порядок или меньше, чем многие другие популярные языки (Python и т.д.). Поскольку исходный код Lua настолько мал и прост, вполне разумно просто включить всю реализацию Lua в исходное дерево, если вы хотите избежать добавления внешней зависимости.
-
Очень быстро. Интерпретатор Lua намного быстрее, чем большинство языков сценариев (опять же, порядок не редкость), а LuaJIT2 - очень хороший JIT-компилятор для некоторых популярных архитектур процессора ( x86, arm, mips, ppc). Использование LuaJIT может часто ускорять работу на другой порядок, и во многих случаях результат приближается к скорости C. LuaJIT также является "заменой" для стандартного Lua 5.1: никаких изменений приложения или пользовательского кода не требуется используйте его.
-
Имеет LPEG. LPEG - это библиотека грамматики выражения Parsing Expression для Lua, которая обеспечивает очень простой, мощный и быстрый синтаксический анализ, подходящий как для больших, так и для небольших задач; это отличная замена для yacc/lex/hairy-regexps. [Я написал парсер, использующий LPEG и LuaJIT, который намного быстрее, чем синтаксис yacc/lex, который я пытался подражать, и было очень легко и просто создать.] LPEG - дополнительный пакет для Lua, но хорошо -worth get (это один исходный файл).
-
Имеет отличный C-интерфейс, который с удовольствием вызывает Lua от C или звонит C из Lua. Для взаимодействия больших/сложных библиотек С++ можно использовать SWIG или любое из нескольких генераторов интерфейсов (можно также просто использовать Lua simple C-интерфейс с С++, конечно).
-
Имеет либеральное лицензирование ( "BSD-like" ), что означает, что Lua может быть встроен в проприетарные проекты, если вы хотите, и совместим с GPL для проектов FOSS.
-
Очень, очень элегантный. Это не lisp, поскольку он не основан на cons-cell, но он показывает явное влияние на языки, такие как схема, с прямым и привлекательным синтаксисом. Подобно схеме (по крайней мере, в ней более ранних воплощений), она стремится к "минимальному", но неплохо балансирует с удобством использования. Для кого-то с фоном lisp (как и я!), Многое о Lua будет казаться знакомым и "иметь смысл", несмотря на различия.
-
Очень гибкий, и такие функции, как metatables, позволяют легко интегрировать типы и операции, специфичные для домена.
-
Имеет простой, привлекательный и доступный синтаксис. Это может быть не таким преимуществом по сравнению с lisp для существующих пользователей lisp, но может быть актуальным, если вы намерены писать сценарии для конечных пользователей.
-
Предназначен для встраивания и, кроме того, небольшого размера и быстрой скорости, имеет различные функции, такие как инкрементный GC, который делает использование языка сценариев более жизнеспособным в таких контекстах.
-
Имеет долгую историю, ответственные и профессиональные разработчики, которые хорошо оценили, как они развивали язык за последние два десятилетия.
-
Имеет яркое и дружелюбное пользовательское сообщество.
Ответ 2
Вы не указали, какую платформу вы используете, но если она будет способна использовать LuaJIT 2, я бы, конечно, пошел на это, поскольку скорости выполнения приближаются к компилируемому коду, а взаимодействие с кодом C просто стало намного проще с библиотекой FFI.
Я не перестаю знать другие встраиваемые языки сценариев, поэтому я не могу сравнивать их действия и методы работы с таблицами.
Lua в основном работает со ссылками: все функции, пользовательские данные, таблицы используются по ссылке и собираются на следующем запуске gc, когда ссылки на данные не оставлены.
Строки интернализированы, поэтому определенная строка находится в памяти только один раз.
Следует учитывать, что вам следует избегать создания и последующего отбрасывания нагрузок таблиц, поскольку это может замедлить цикл GC (как объясняется в названном вами Lua gem).
Для синтаксического анализа образца кода я бы посмотрел библиотеку LPEG
Ответ 3
Существует ряд вариантов реализации высокопроизводительных встроенных компиляторов. Один из них - Mono VM, он, естественно, поставляется с десятками уже выполненных на высоком уровне языков высокого качества, и он вполне вложим (см., Как Second Life использует его). Также возможно использовать LLVM - похоже, что ваш DSL не является сложным, поэтому реализация специального компилятора не будет большой проблемой.
Ответ 4
Мне довелось работать над проектом, который имеет некоторые части, которые похожи на ваш проект. Это кросс-платформенная система, работающая на Win-CE, Android, iOS. Мне нужно максимально использовать код, совместимый с кросс-платформой, C/С++ сочетать с встраиваемым языком - хороший выбор. вот мое решение, связанное с вашими вопросами.
- Если бы вы были в моем положении, какой язык вы бы выбрали?
DSL в моем проекте похож на ваш. для производительности я написал компилятор с Yacc/Lex для компиляции DSL в двоичный файл для выполнения и кучу API для получения информации из двоичного кода, но это раздражает, когда есть что-то, модифицированное в синтаксисе DSL, мне нужно изменить как компилятор, так и API, поэтому я оставил DSL, превратился в XML (не пишу XML напрямую, хорошо определенная схема достойна), я написал общий компилятор, преобразующий XML в таблицу lua, переопределяю API с помощью lua. делая это, я получил два преимущества: читаемость и гибкость, без ощутимой деградации производительности.
- Есть ли какие-либо альтернативы, которые я должен рассмотреть (не предлагайте языки, которые не имеют внедряемой реализации). Возможно, Javascript v8?
Прежде чем выбрать lua, я рассмотрю Embedded Ch (в основном используется в промышленной системе управления), встроенный lisp и lua, наконец, lua stand потому что lua хорошо интегрирован с C, lua имеет преуспевающее сообщество, а lua легко учиться для другого члена команды. что касается Javascript v8, ему нравится использовать паром-молот для взлома орехов, если он используется во встроенной системе реального времени.
- Улучшает ли lisp домен? Я не думаю, что lua и lisp отличаются друг от друга тем, что они предоставляют. Вызовите меня: D
Для моего домена lisp и lua имеют одинаковую способность в семантике, они могут легко обрабатывать DSL на основе XML, или вы даже можете написать простой компилятор, преобразующий XML в список lisp или lua. они оба могут легко обрабатывать логику домена. но lua лучше интегрируется с C/С++, это то, к чему стремится lua.
- Есть ли другие свойства (например, ниже), о которых я должен думать?
Работа в одиночку или с членами команды также является весовым фактором выбора решений. в настоящее время не так много программистов знакомы с языком lisp.
- Я утверждаю, что любая форма встроенной базы данных IO (см. пример DSL ниже для контекста) затмевает вызов языка сценариев на порядки, и этот выбор не добавит больших накладных расходов на общую пропускную способность. Я на правильном пути?: D
здесь - это список характеристик языков программирования, здесь представляет собой список времени доступа компьютерных компонентов. если ваша система привязана к IO, накладные расходы script не являются ключевыми. моя система - система O & M (эксплуатация и обслуживание), производительность script невелика.