2

明示的な関数セットと事前定義された変数の使用を可能にする任意の数値式をユーザーが入力できるようにすると仮定します。

これを解釈するのは非常に簡単ですが、パフォーマンスが重要な要素である場合はどうでしょうか?

式を含む文字列を (実行時に) 変数の異なる値で 20K 回実行できるものにコンパイルする方法が必要です。

4

3 に答える 3

2

したがって、実際には文字列を (最終的には) 型指定されたデリゲートに解析する必要があります。

1 つのオプションとして、文字列を に解析Expressionし、ラムダにコンパイルできます。これは非常に複雑ですが、私はこれを行うコードをいくつか持っていますが、すでに完全に機能している既存のパーサーがあるかもしれません。

些細なExpression例として:

    var x = Expression.Parameter(typeof(double), "x");
    var y = Expression.Parameter(typeof(double), "y");
    var body = Expression.Multiply(x, y);
    var func = Expression.Lambda<Func<double, double,double>>(body, x, y).Compile();

    double z = func(123.45, 678.90);

問題は解析コードの残りの部分です;-p

先週stringtoパーサーを書きましたが、通常ここに投稿するよりも多くのコードです... 300 行を超えています (特注の外部関数や名前付き引数の認識は含まれていません (現在は匿名の "?" プレースホルダーを使用しています)。 Expression)。

しかし、(あなたが言うように)解釈が簡単な場合は、同様のコードを使用して、Expressionコンパイルできるものを書くことができますか?

于 2008-12-19T09:03:57.607 に答える
2

Microsoft による Linq サンプルには、拡張可能な Linq パーサーの実装が既に含まれています。

sealed class Order
{
  public double SubTotal { get; set; }
  public double Shipping { get; set; }
}
static void Main()
{
  var calculateTotal = DynamicExpression
    .ParseLambda<Order, double>("SubTotal*@0+Shipping", 0.12)
    .Compile();

  var order = new Order
  {
    SubTotal = 124.99,
    Shipping = 7.99
  };
  Console.WriteLine(calculateTotal(order));
  Console.ReadLine();
}

ソースについてはDbLinq プロジェクトをチェックアウトするか、詳細についてはこの投稿をチェックアウトできます。

于 2008-12-19T10:12:54.193 に答える
1

C# 4.0 では、これは非常に簡単でわかりやすいものになります。ただし、C# 4.0 より前では、Microsoft.JScriptライブラリを使用してそれを実現することをお勧めします。

これだけで十分です: http://www.odetocode.com/Articles/80.aspx

于 2008-12-19T09:03:11.197 に答える