16

Expression<T>がコンパイルされると、結果のコードはフレームワークによって暗黙的にキャッシュされますか? Regexフレームワークが最後のいくつかの正規表現を暗黙的にコンパイルしてキャッシュする静的メソッドの方針に沿って考えています。

コンパイルされたExpression<T>オブジェクトがキャッシュされていない場合、コンパイル時間を短縮するためのベスト プラクティスや、式を手動でキャッシュした場合に問題を引き起こす可能性のある問題を推奨できますか?

public MyResultType DoSomething(int arg1, int arg2)
{
    var result = invokeHandler(
        (IDoSomethingHandler h) => h.DoSomething(arg1, arg2)
    );
    return result;
}

private TResult invokeHandler<T, TResult>(Expression<Func<T, TResult>> action)
    where T : class
{
    // Here, I might want to check to see if action is already cached.

    var compiledAction = action.Compile();
    var methodCallExpr = action as MethodCallExpression;

    // Here, I might want to store methodCallExpr in a cache somewhere.

    var handler = ServiceLocator.Current.GetInstance<T>();
    var result = compiledAction(handler);

    return result;
}

この例では、コンパイルされた式をキャッシュすると、スタック内の適切な場所から値を取得するのではなく、式がコンパイルされた時点のarg1andの値が使用されるのではないかと少し心配しています (つまり、arg2現在の値を取得するのではなく)。

4

2 に答える 2

11

いいえ; 私はそうだとは思いません。キャッシュする場合は、Delegate参照を保持する必要があります(通常Func<...>またはAction<...>)。同様に、最高のパフォーマンスを実現したい場合は、パラメーター化された式としてコンパイルするため、呼び出し時にさまざまな値を送信できます。

この場合、言い換えると次のようになります。

public MyResultType DoSomething(int arg1, int arg2)
{
    var result = invokeHandler(
        (IDoSomethingHandler h, int a1, int a2) => h.DoSomething(a1, a2),
        arg1, arg2);
    return result;
}

private TResult invokeHandler<T, TResult>(Expression<Func<T,int,int,TResult>> action,
    int arg1, int arg2)
    where T : class
{
    // Here, I might want to check to see if action is already cached.

    var compiledAction = action.Compile();
    var methodCallExpr = action as MethodCallExpression;

    // Here, I might want to store methodCallExpr in a cache somewhere.

    var handler = ServiceLocator.Current.GetInstance<T>();
    var result = compiledAction(handler, arg1, arg2);

    return result;
}

つまり、式の数値パラメータを作成し、実行時に実際の数値を渡します(式の定数ではありません)。

于 2008-11-03T15:02:04.537 に答える
2

ラムダエクスプレッションは自動的にキャッシュされません。そのためには、独自のキャッシュ/メモ化アルゴリズムを実装する必要があります。関連するStackoverflowの質問を確認してください:

ラムダ式で評価された値をキャッシュすることは可能ですか?

ラムダ式はC#で遅延評価されることに注意することが重要です。

于 2008-11-03T15:02:43.460 に答える