Lua vs Embedded Lisp i potencjalni inni kandydaci. do przetwarzania danych w oparciu o Zestaw

Aktualny wybór: lua-jit. Imponujące benchmarki, przyzwyczajam się do składni. Pisanie wysokowydajnego ABI będzie wymagało starannego rozważenia, w jaki sposób będę struktura mojego C++.

Inne interesujące pytania

  1. Gambit-C i Guile jako języki osadzalne
  2. (Mają możliwość uruchamiania z wyłączonym kolektorem, a wywołanie kolektora na końcu procesu przetwarzania jest zawsze opcja).

Tło

Pracuję nad systemem przetwarzania dużych wolumenów (złożonych) w czasie rzeczywistym. Mam DSL, który reprezentuje schemat struktury zdarzeń u źródła, format pamięci masowej, pewne konstrukcje specyficzne dla domeny, odpalanie zdarzeń wewnętrznych (do struktury i napędzania przetwarzania ogólnego przeznaczenia) i kodowanie pewnych etapów przetwarzania, które zawsze się zdarzają.

DSL wygląda dość podobnie do SQL, w rzeczywistości używam Berkeley db (poprzez interfejs sqlite3) do długoterminowego przechowywania wydarzeń. ważną częścią jest to, że przetwarzanie zdarzeń odbywa się na podstawie zestawów, takich jak SQL . Doszedłem jednak do wniosku, że nie powinienem dodawać logiki przetwarzania ogólnego do DSL, a raczej osadzać lua lub lisp, aby się tym zająć.

Rdzeń przetwarzania jest zbudowany arround boost:: asio, jest wielowątkowy, rpc odbywa się za pomocą buforów protokołów, zdarzenia są kodowane za pomocą bufora protokołu biblioteka IO --tzn. zdarzenia nie są ustrukturyzowane używając obiektu bufora protokołu używają tylko tej samej biblioteki kodowania/dekodowania. Stworzę obiekt dataset, który zawiera wiersze, całkiem podobny do tego, jak silnik bazy danych przechowuje w zestawach pamięci. etapy przetwarzania w DSL zostaną najpierw uwzględnione, a następnie przedstawione ogólnej logice przetwarzania.

Niezależnie od tego, jakiego wbudowywalnego środowiska skryptowego używam, każdy wątek w moim rdzeniu będzie prawdopodobnie potrzebował własnego środowiska wbudowanego języka (tak wymaga lua być przynajmniej jeśli wykonujesz pracę wielowątkową).

Pytanie(y)

Obecnie wybór jest pomiędzy lispem ECL i lua. Biorąc pod uwagę, że wydajność i przepustowość są dużym wymaganiem, oznacza to, że zminimalizowanie alokacji pamięci jest wysoce pożądane:

  1. Gdybyś był na moim miejscu, który język byś wybrał ?

  2. Czy są jakieś alternatywy, które powinienem rozważyć (nie sugeruj języków, które nie mają wbudowanego wdrożenie). Javascript v8 może ?

  3. Czy lisp lepiej pasuje do domeny ? Nie sądzę, aby lua i lisp różniły się tak bardzo pod względem tego, co zapewniają. Call me out: d

  4. Czy są jakieś inne właściwości (takie jak te poniżej), o których powinienem myśleć ?

  5. Twierdzę, że jakakolwiek forma wbudowanej bazy danych IO (patrz przykład DSL poniżej dla kontekstu) przyćmiewa wywołanie języka skryptowego na rząd wielkości, i że wybranie albo nie dodaj dużo narzutu do ogólnej przepustowości. Jestem na dobrej drodze ? : D

Pożądane Właściwości

  1. Chciałbym mapować mój zestaw danych na listę Lispu lub tabelę lua i chciałbym zminimalizować zbędne kopie danych. Na przykład dodanie wiersza z jednego zbioru danych do drugiego powinno próbować użyć semantyki referencji, jeśli obie tabele mają ten sam kształt.

  2. Mogę zagwarantować, że zestaw danych, który jest przekazywany jako dane wejściowe, nie ulegnie zmianie, podczas gdy ja wykonałem połączenie lua / lisp. Chcę, aby lua i lisp wymusiły nie zmienianie zbioru danych, jeśli to możliwe.

  3. Po zakończeniu wbudowanego wywołania zbiory danych powinny zostać zniszczone, wszelkie utworzone referencje muszą być zastąpione kopiami (chyba).

Przykład DSL

Dołączam DSL dla przyjemności oglądania, abyś mógł zorientować się, co próbuję osiągnąć. Uwaga: DSL nie pokazuje przetwarzania ogólnego przeznaczenia.
// 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);
  } 
}

To projekt jest składnikiem projektu badawczego Ph. D i jest / będzie wolnym oprogramowaniem. Jeśli jesteś zainteresowany współpracą ze mną (lub wkładem) w ten projekt, zostaw komentarz: D

Author: Community, 2011-10-27

4 answers

Zdecydowanie zgadzam się z punktami @jpjacobs. Lua jest doskonałym wyborem do osadzania, chyba że jest coś bardzo konkretnego w Lispie, czego potrzebujesz (na przykład, jeśli Twoje dane mapują się szczególnie dobrze do komórek cons).

Używam Lispa od wielu lat, BTW, i bardzo lubię składnię Lispa, ale w dzisiejszych czasach zazwyczaj wybieram Lua. Chociaż lubię język lisp , nie znalazłem jeszcze implementacji lisp , która uchwyci wspaniałą równowagę funkcje/smallness / usability dla osadzonych używać sposób Lua robi.

Lua:

  1. Jest bardzo mały, zarówno źródłowy, jak i binarny, o rząd wielkości lub bardziej mniejszy niż wiele bardziej popularnych języków (Python itp.). Ponieważ kod źródłowy Lua jest tak mały i prosty, jest całkowicie rozsądne, aby po prostu włączyć całą implementację Lua do swojego drzewa źródeł, jeśli chcesz uniknąć dodawania zewnętrznej zależności.

  2. Jest bardzo szybki. Tłumacz Lua jest znacznie szybszy niż większość języków skryptowych (ponownie, rząd wielkości nie jest rzadkością), a LuaJIT2 jest bardzo dobrym kompilatorem JIT dla niektórych popularnych architektur procesorów (x86, arm, mips, ppc). Użycie LuaJIT może często przyspieszyć działanie o Inny rząd wielkości, a w wielu przypadkach wynik zbliża się do prędkości C. LuaJIT jest również" drop-in " zamiennikiem standardowego Lua 5.1: do jego użycia nie są wymagane żadne zmiany aplikacji ani kodu użytkownika.

  3. MA LPEG. LPEG jest biblioteką "Parsing Expression Grammar" dla Lua, która umożliwia bardzo łatwe, wydajne i szybkie parsowanie, odpowiednie zarówno do dużych, jak i małych zadań; jest to świetny zamiennik dla Yacc/lex / hairy-regexps. [Napisałem parser za pomocą LPEG i LuaJIT, który jest znacznie szybszy niż parser yacc / lex, który próbowałem emulować, i był bardzo łatwy i prosty w tworzeniu.] LPEG to dodatkowy pakiet dla Lua, ale warto go zdobyć (to jedno źródło plik).

  4. Posiada świetny Interfejs C, który sprawia przyjemność wywoływać Lua z C, lub wywoływać C z Lua. Do łączenia dużych / złożonych bibliotek C++, można użyć SWIG, lub dowolnego z wielu generatorów interfejsów (można również po prostu użyć prostego interfejsu C Lua z C++ Oczywiście).

  5. Posiada liberalne licencje ("podobne do BSD"), co oznacza, że Lua może być osadzona w projektach prawnie zastrzeżonych i jest zgodna z GPL dla FOSS projekty.

  6. Jest bardzo, bardzo elegancki. Nie jest to lisp, ponieważ nie jest oparty na cons-komórkach, ale wykazuje wyraźne wpływy z języków takich jak scheme, z prostą i atrakcyjną składnią. Podobnie jak scheme (przynajmniej we wcześniejszych wcieleniach), ma tendencję do "minimalizmu", ale dobrze balansuje to z użytecznością. Dla kogoś z lispowym tłem(jak ja!), wiele o Lua wyda się znajome i "ma sens", pomimo różnice.

  7. Jest bardzo elastyczny, a takie funkcje, jak metatable, pozwalają łatwo integrować typy i operacje specyficzne dla domeny.

  8. Ma prostą, atrakcyjną i przystępną składnię. Może to nie być taka przewaga nad lispem dla istniejących użytkowników Lispu, ale może być istotne, jeśli chcesz, aby użytkownicy końcowi pisali Skrypty.

  9. Jest przeznaczony do osadzania, a oprócz niewielkich rozmiarów i dużej prędkości, ma różne funkcje, takie jak przyrostowe GC, które sprawiają, że korzystanie z języka skryptowego jest bardziej opłacalne w takich kontekstach.

  10. Ma długą historię i odpowiedzialnych i profesjonalnych programistów, którzy wykazali się dobrą oceną w jaki sposób ewoluowali język w ciągu ostatnich 2 dekad.

  11. Ma żywą i przyjazną społeczność użytkowników.

 32
Author: snogglethorpe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-18 22:57:24

Nie podajesz, jakiej platformy używasz, ale jeśli byłaby w stanie używać LuaJIT 2 z pewnością bym się na to zgodził, ponieważ szybkość wykonania zbliża się do prędkości skompilowanego kodu, a łączenie się z kodem C stało się o wiele łatwiejsze dzięki bibliotece FFI.

Nie kończę znać inne wbudowane języki skryptowe, więc nie mogę naprawdę porównać, co mogą zrobić, i jak działają z tabel.

Lua działa głównie z referencjami: wszystkie funkcje, userdata, tabele są używane przez odniesienia i są zbierane podczas następnego uruchomienia gc, gdy nie ma odniesień do danych. Ciągi są internalizowane, więc pewien ciąg jest w pamięci tylko raz. Należy wziąć pod uwagę to, że należy unikać tworzenia, a następnie odrzucania mnóstwa tabel, ponieważ może to spowolnić cykl GC (jak wyjaśniono w klejnocie Lua, który cytowałeś)

Aby przeanalizować próbkę kodu, rzuciłbym okiem na bibliotekę LPEG

 6
Author: jpjacobs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-28 08:05:21

Istnieje wiele opcji implementacji wysoko wydajnych wbudowanych kompilatorów. Jednym z nich jest mono VM, naturalnie jest wyposażony w dziesiątki już wykonanych języków wysokiej jakości zaimplementowanych na nim, i jest dość osadzalny(zobacz, jak Second Life używa go). Możliwe jest również użycie LLVM-wygląda na to, że Twój DSL nie jest skomplikowany, więc wdrożenie kompilatora ad hoc nie byłoby wielką sprawą.

 2
Author: SK-logic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-28 09:17:35

Zdarzyło mi się pracować nad projektem, który ma pewne części, które są podobne do projektu, jest to system wieloplatformowy działający na Win-CE, Android,iOS, muszę zmaksymalizować kod cross-platform-able, C / C++ połączyć z językiem osadzanym jest dobrym wyborem. oto moje rozwiązanie związane z Twoimi pytaniami.

    Gdybyś był na moim miejscu, który język byś wybrał ?

DSL w moim projekcie jest podobny do twojego. do wykonania napisałam kompilator z Yacc / Lex skompilować DSL do binary dla runtime i kilka API, aby uzyskać informacje z binary, ale to denerwujące, gdy jest coś zmodyfikowane w składni DSL, muszę zmodyfikować zarówno kompilator i API, więc abondoned DSL, zamienione w XML (nie pisz bezpośrednio XML, dobrze zdefiniowany schemat jest godny), napisałem ogólny kompilator konwersji XML do tabeli lua, reimplement API z lua. dzięki temu mam dwie zalety: czytelność i elastyczność, bez dostrzegalnych pogorszenie wydajności.

  1. czy są jakieś alternatywy, które powinienem rozważyć(nie sugeruj języków, które nie mają wbudowanej implementacji). Javascript v8 może ?

Przed wyborem lua uważam, że Embedded Ch (używany głównie w industrial control system) , embedded lisp i lua w końcu wyróżniają się lua, ponieważ lua jest dobrze zintegrowana z C, Lua ma dobrze prosperującą społeczność, a lua jest łatwa do nauczenia się dla innego członka zespołu. dotyczące Javascript v8, to jak używanie młota parowego do łamania orzechów, jeśli jest używany w osadzonym systemie czasu rzeczywistego.

  1. czy lisp lepiej pasuje do domeny ? Nie sądzę, aby lua i lisp różniły się tak bardzo pod względem tego, co zapewniają. Call me out: d

Dla mojej domeny, lisp i lua mają taką samą zdolność w semantyce, obie mogą łatwo obsługiwać DSL oparte na XML, lub możesz nawet napisać prosty kompilator konwertujący XML na lisp list lub tabelę lua. oba mogą obsługiwać domenę logika łatwo. ale lua jest lepiej zintegrowany z C / C++, do tego zmierza lua.

  1. czy są jakieś inne właściwości (jak te poniżej), o których powinienem myśleć ?

Praca w pojedynkę lub z członkami zespołu jest również czynnikiem decydującym o wyborze rozwiązania. obecnie niewielu programistów zna język podobny do Lispu.

  1. twierdzę, że każda forma wbudowanej bazy danych IO (patrz przykład DSL poniżej dla kontekstu) wywołanie języka skryptowego na rządkach wielkości, a to zbieranie albo nie doda wiele narzutu do ogólnej przepustowości. Jestem na dobrej drodze ? : D

Tutaj {[10] } jest lista wydajności języków programowania, tutaj {[10] } jest lista czasu dostępu do komponentów komputera. jeśli Twój system jest związany z IO, narzut skryptu nie jest kluczowym punktem. mój system to system O & M (Operation & Maintenance), wydajność skryptu jest znikoma.

 1
Author: Jimmy Zhang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-27 22:50:27