Подтвердить что ты не робот

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

4b9b3361

Ответ 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. делая это, я получил два преимущества: читаемость и гибкость, без ощутимой деградации производительности.

  1. Есть ли какие-либо альтернативы, которые я должен рассмотреть (не предлагайте языки, которые не имеют внедряемой реализации). Возможно, Javascript v8?

Прежде чем выбрать lua, я рассмотрю Embedded Ch (в основном используется в промышленной системе управления), встроенный lisp и lua, наконец, lua stand потому что lua хорошо интегрирован с C, lua имеет преуспевающее сообщество, а lua легко учиться для другого члена команды. что касается Javascript v8, ему нравится использовать паром-молот для взлома орехов, если он используется во встроенной системе реального времени.

  1. Улучшает ли lisp домен? Я не думаю, что lua и lisp отличаются друг от друга тем, что они предоставляют. Вызовите меня: D

Для моего домена lisp и lua имеют одинаковую способность в семантике, они могут легко обрабатывать DSL на основе XML, или вы даже можете написать простой компилятор, преобразующий XML в список lisp или lua. они оба могут легко обрабатывать логику домена. но lua лучше интегрируется с C/С++, это то, к чему стремится lua.

  1. Есть ли другие свойства (например, ниже), о которых я должен думать?

Работа в одиночку или с членами команды также является весовым фактором выбора решений. в настоящее время не так много программистов знакомы с языком lisp.

  1. Я утверждаю, что любая форма встроенной базы данных IO (см. пример DSL ниже для контекста) затмевает вызов языка сценариев на порядки, и этот выбор не добавит больших накладных расходов на общую пропускную способность. Я на правильном пути?: D

здесь - это список характеристик языков программирования, здесь представляет собой список времени доступа компьютерных компонентов. если ваша система привязана к IO, накладные расходы script не являются ключевыми. моя система - система O & M (эксплуатация и обслуживание), производительность script невелика.