35

現在の選択: lua-jit。印象的なベンチマーク、私は構文に慣れています。高性能のABIを作成するには、C++をどのように構成するかを慎重に検討する必要があります。

その他の興味のある質問

  1. 埋め込み可能な言語としてのGambit-CとGuile
  2. Luaパフォーマンスのヒント(コレクターを無効にして実行するオプションがあり、処理実行の最後にコレクターを呼び出すことは常にオプションです)。

バックグラウンド

私はリアルタイムの大容量(複合)イベント処理システムに取り組んでいます。ソースでのイベント構造のスキーマ、ストレージ形式、特定のドメイン固有の構造、内部イベントの発生(汎用処理を構造化および駆動するため)、および常に発生​​する特定の処理ステップのエンコードを表すDSLがあります。

DSLはSQLに非常によく似ています。実際、私はイベントの長期保存にberkeley db(sqlite3インターフェイス経由)を使用しています。ここで重要なのは、イベントの処理がSQLのようにセットベースで行われることです。しかし、DSLに汎用処理ロジックを追加するのではなく、luaまたはlispを埋め込んでこれを処理する必要があるという結論に達しました。

処理コアはboost::asioを中心に構築されており、マルチスレッドであり、rpcはプロトコルバッファを介して実行され、イベントはプロトコルバッファIOライブラリを使用してエンコードされます。つまり、イベントはプロトコルバッファオブジェクトを使用して構造化されておらず、同じエンコーディングを使用します。 /decodingライブラリ。データベースエンジンがメモリセットに格納する方法と非常によく似た、行を含むデータセットオブジェクトを作成します。DSLの処理ステップは最初に処理され、次に汎用処理ロジックに提示されます。

使用する埋め込み可能なスクリプト環境に関係なく、処理コアの各スレッドには、おそらく独自の埋め込み言語環境が必要です(つまり、少なくともマルチスレッド作業を行う場合は、luaがそれを必要とします)。

質問)

現時点での選択は、lispECLとluaのどちらかです。パフォーマンスとスループットが強力な要件であることを念頭に置いて、これはメモリ割り当てを最小限に抑えることが非常に望ましいことを意味します。

  1. もしあなたが私の立場にあったら、あなたはどの言語を選びますか?

  2. 検討すべき代替案はありますか(埋め込み可能な実装がない言語を提案しないでください)。Javascript v8はおそらく?

  3. lispはドメインによりよく適合しますか?luaとlispは、提供するものに関してそれほど異なるとは思いません。私を呼んでください:D

  4. 私が考えるべき他のプロパティ(以下のような)はありますか?

  5. あらゆる形式の組み込みデータベースIO(コンテキストについては以下のDSLの例を参照)は、スクリプト言語の呼び出しを桁違いに小さくし、どちらを選択しても、全体的なスループットに大きなオーバーヘッドは追加されないと断言します。私は正しい方向に進んでいますか?:D

必要なプロパティ

  1. データセットをlispリストまたはluaテーブルにマッピングしたいのですが、冗長なデータコピーを最小限に抑えたいと思います。たとえば、あるデータセットから別のデータセットに行を追加する場合、両方のテーブルの形状が同じである場合は、参照セマンティクスを使用する必要があります。

  2. lua / lisp呼び出しを行っている間、入力として渡されるデータセットが変更されないことを保証できます。luaとlispに、可能であればデータセットも変更しないように強制したいと思います。

  3. 埋め込まれたコールエンドのデータセットを破棄した後、作成された参照をコピーに置き換える必要があります(私は推測します)。

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);
  } 
}

このプロジェクトは博士課程の研究プロジェクトの構成要素であり、自由ソフトウェアです。このプロジェクトで私と一緒に仕事をする(または貢献する)ことに興味がある場合は、コメントを残してください:D

4

4 に答える 4

36

@jpjacobsの意見に強く同意します。 Luaは、必要なlispについて非常に具体的なものがない限り、埋め込みに最適です(たとえば、データがコンセルに特によくマッピングされている場合)。

ところで、私は何年もの間lispを使ってきました、そして私はlisp構文がとても好きです、しかし最近私は一般的にLuaを選びます。私はlisp言語が好きですが、Luaのように組み込み用途の機能/小ささ/使いやすさの素晴らしいバランスをとらえるlisp実装をまだ見つけていません。

Lua

  1. ソースとバイナリの両方で非常に小さく、より一般的な多くの言語(Pythonなど)よりも1桁以上小さいです。Luaソースコードは非常に小さくシンプルなので、外部依存関係の追加を避けたい場合は、Lua実装全体をソースツリーに含めるのが完全に合理的です。

  2. とても速いです。Luaインタープリターは、ほとんどのスクリプト言語よりもはるかに高速であり(ここでも、桁違いに珍しいことではありません)、LuaJIT2は、いくつかの一般的なCPUアーキテクチャー(x86、arm、mips、ppc)に非常に優れたJITコンパイラーです。LuaJITを使用すると、多くの場合、速度が1桁速くなり、多くの場合、結果はCの速度に近づきます。LuaJITは、標準のLua5.1の「ドロップイン」代替品でもあります。アプリケーションやユーザーコードを変更する必要はありません。これを使って。

  3. LPEGがあります。LPEGは、Lua用の「ParsingExpression Grammar」ライブラリであり、非常に簡単で強力かつ高速な解析を可能にし、大規模なタスクと小規模なタスクの両方に適しています。これは、yacc / lex/hairy-regexpsの優れた代替品です。[LPEGとLuaJITを使用してパーサーを作成しました。これは、エミュレートしようとしたyacc / lexパーサーよりもはるかに高速で、作成が非常に簡単で簡単です。] LPEGはLuaのアドオンパッケージですが、優れています。 -取得する価値があります(これは1つのソースファイルです)。

  4. 優れたCインターフェースを備えているため、CからLuaに電話をかけたり、LuaからCに電話をかけたりすることができます。大規模/複雑なC++ライブラリとのインターフェースには、SWIG、または多数のインターフェースジェネレーターのいずれかを使用できます(もちろん、Luaの単純なCインターフェースをC ++で使用することもできます)。

  5. リベラルなライセンス(「BSDライク」)があります。つまり、必要に応じてLuaをプロプライエタリプロジェクトに組み込むことができ、FOSSプロジェクトとGPL互換です。

  6. とても、とてもエレガントです。それはコンセルに基づいていないという点でLispではありませんが、単純で魅力的な構文で、schemeのような言語からの明確な影響を示しています。スキームのように(少なくとも初期の化身では)、それは「最小限」に向かう傾向がありますが、それを使いやすさとバランスをとるのに良い仕事をします。さわやかな背景を持つ人(私のように!)にとって、Luaについての多くは、違いにもかかわらず、なじみがあり、「理にかなっている」ように見えます。

  7. 非常に柔軟性があり、メタテーブルなどの機能により、ドメイン固有のタイプと操作を簡単に統合できます。

  8. シンプルで魅力的で親しみやすい構文を持っています。これは、既存のlispユーザーにとってlispに比べてそれほど有利ではないかもしれませんが、エンドユーザーにスクリプトを書かせようとする場合は関係があるかもしれません。

  9. 埋め込み用に設計されており、サイズが小さく高速であることに加えて、このようなコンテキストでスクリプト言語の使用をより実行可能にするインクリメンタルGCなどのさまざまな機能があります。

  10. 長い歴史があり、責任あるプロの開発者は、過去20年間に言語をどのように進化させてきたかについて適切な判断を示してきました。

  11. 活気に満ちたフレンドリーなユーザーコミュニティがあります。

于 2011-10-28T09:54:48.700 に答える
6

使用しているプラ​​ットフォームは明記していませんが、 LuaJIT 2を使用できる場合は、実行速度がコンパイル済みコードの速度に近づき、Cコードとのインターフェースが非常に簡単になるため、私は確かにそれを選びます。 FFIライブラリ。

私は他の埋め込み可能なスクリプト言語を知るのをやめないので、それらが何ができるのか、そしてそれらがテーブルでどのように機能するのかを実際に比較することはできません。

Luaは主に参照で機能します。すべての関数、userdata、テーブルは参照によって使用され、データへの参照が残っていない場合、次のgc実行で収集されます。文字列は内部化されているため、特定の文字列がメモリに1回だけ存在します。考慮すべきことは、テーブルのロードを作成してから破棄することは避けるべきであるということです。これは、GCサイクルを遅くする可能性があるためです(引用したLua gemで説明されています)。

コードサンプルを解析するために、LPEGライブラリを見てみましょう

于 2011-10-28T08:05:21.727 に答える
2

高性能の組み込みコンパイラを実装するためのオプションがいくつかあります。1つはMonoVMで、その上にすでに作成された高品質の言語が数十個実装されており、非常に埋め込み可能です(Second Lifeがどのように使用しているかを参照してください)。LLVMを使用することも可能です-DSLは複雑ではないように見えるので、アドホックコンパイラの実装は大したことではありません。

于 2011-10-28T09:17:35.267 に答える
2

私はたまたまあなたのプロジェクトに似た部分があるプロジェクトに取り組んでいます、それはWin-CE、Android、iOSで実行されているクロスプラットフォームシステムです、私はクロスプラットフォーム対応のコードを最大化する必要があります、C /C++は埋め込み可能な言語は良い選択です。これがあなたの質問に関連する私の解決策です。

  1. もしあなたが私の立場にあったら、あなたはどの言語を選びますか?

私のプロジェクトのDSLはあなたのものと似ています。パフォーマンスのために、実行時にDSLをバイナリにコンパイルするYacc / Lexを使用してコンパイラを作成し、バイナリから情報を取得するために一連のAPIを作成しましたが、DSL構文に変更が加えられている場合は、コンパイラとAPIの両方を変更する必要があります。 、それで私はDSLを結合し、XMLに変換しました(XMLを直接記述しないでください、明確に定義されたスキーマは価値があります)、XMLをluaテーブルに変換する一般的なコンパイラを記述し、luaでAPIを再実装しました。これを行うことで、2つの利点が得られました。知覚できるパフォーマンスの低下なしに、読みやすさと柔軟性です。

  1. 検討すべき代替案はありますか(埋め込み可能な実装がない言語を提案しないでください)。Javascript v8はおそらく?

luaを選択する前に、Embedded Ch(主に産業用制御システムで使用される)、Embedded lisp、luaを検討しましたが、luaはCと十分に統合されており、コミュニティが繁栄しており、luaは他の人にとっても習得しやすいため、ついにluaが際立っています。チームメンバー。Javascript v8に関しては、組み込みのリアルタイムシステムで使用する場合、蒸気ハンマーを使用してナットを割るようなものです。

  1. lispはドメインによりよく適合しますか?luaとlispは、提供するものに関してそれほど異なるとは思いません。私を呼んでください:D

私のドメインでは、lispとluaはセマンティックで同じ機能を持っており、どちらもXMLベースのDSLを簡単に処理できます。あるいは、XMLをlispリストまたはluaテーブルに変換する単純なコンパイラーを作成することもできます。どちらもドメインロジックを簡単に処理できます。しかし、luaはC / C ++とよりよく統合されており、これがluaが目指していることです。

  1. 他に考えるべきプロパティ(以下のような)はありますか?

単独で、またはチームメンバーと一緒に作業することも、ソリューション選択の重要な要素です。今日では、Lispのような言語に精通しているプログラマーはそれほど多くありません。

  1. あらゆる形式の組み込みデータベースIO(コンテキストについては以下のDSLの例を参照)は、スクリプト言語の呼び出しを桁違いに小さくし、どちらを選択しても、全体的なスループットに大きなオーバーヘッドは追加されないと断言します。私は正しい方向に進んでいますか?:D

これがプログラミング言語のパフォーマンスのリストであり、これがコンピュータコンポーネントのアクセス時間のリストです。システムがIOバウンドの場合、スクリプトのオーバーヘッドは重要なポイントではありません。私のシステムはO&M(Operation&Maintenance)システムであり、スクリプトのパフォーマンスは重要ではありません。

于 2013-11-18T15:34:01.947 に答える