1

次のコードがあるとします。

ExpressionHelper.GetRouteValuesFromExpression<AccountController>(ax => ax.MyAction("a", "b"));

(ASP.NET MVC Futures アセンブリから)。メソッドはかなり高速です。150 ミリ秒で 10,000 回の反復を実行します。

ここで、コードを次のように変更します。

string a = "a";
string b = "b";
ExpressionHelper.GetRouteValuesFromExpression<AccountController>(ax => ax.MyAction(a, b));

このコードは、15秒で 10,000 回の反復を実行します。

問題は次のコードです。

Expression<Func<object>> lambdaExpression = Expression.Lambda<Func<object>>(Expression.Convert(arg, typeof (object)));

Func<object> func = lambdaExpression.Compile();

value = func()

式を毎回コンパイルするよりも、式から値を取得するためのより良い方法はありますか? これは、ASP.NET MVC リンクの生成速度に大きく影響する可能性があります。

4

3 に答える 3

1

これがボトルネックである場合、式の値とそのコンパイルされた値をローカルにキャッシュしないのはなぜですか? 単純な辞書でうまくいくと思います:

Dictionary<Expression<Action<T>>, Action<T>> m_Cache =
    new Dictionary<Expression<Action<T>>, Action<T>>();

public void GetRouteValuesFromExpression<T>(Expression<Action<T>> expr) {
    Action<T> compiled = null;
    if (!m_Cache.TryGetValue(expr, ref compiled)) {
        compiled = expr.Compile();
        m_Cached.Add(expr, compiled);
    }
    // execute …
}
于 2008-10-20T13:37:32.760 に答える
0

である必要がありFunc<object>ますか?おそらく手動で「キャプチャ」を作成できます。つまり、 a & b; を宣言するタイプがあります。を持っておりFunc<Whatever, object>、これをデリゲートにコンパイルします。次に、実行時に行うことは次のとおりです。

Foo foo = new Foo {A = a, B = b};
return cachedFunc(foo);

Convert(blah, typeof(object)) が何をしているのかよくわかりません-これを明確にできますか? 表現についてはかなりの経験がありますが、これは... 珍しいようです...

于 2008-10-20T14:11:40.723 に答える
0

私は少しいじって、次のことを思いつきました:

var body = (MethodCallExpression)expr.Body;
var arg1 = (MemberExpression)body.Arguments[0];
var contextType = arg1.Member.DeclaringType;
var field = contextType.GetField(arg1.Member.Name);
Console.WriteLine(field.GetValue(…));

exprそれがあなたの引数であると仮定するとExpression<Action<T>>、これはあなたの呼び出しに最初の引数として渡される反映されたフィールドをあなたに与えます(aあなたの場合)。ただし、このフィールドを評価するために必要なコンテキストを抽出できませんでした (最後の行、「…」でマークされた場所)。このコンテキストには、式をコンパイルしないとアクセスできないと思います。結果として、あなたが望むものは不可能です。

私が間違っていることを証明してください。;-)

(実際には、リフレクターを使用しても実行コンテキストが保存されている場所を見つけることができないため、何かを見落とす可能性があるため、よくわかりません。)

于 2008-10-20T14:38:18.753 に答える