【问题标题】:When an Expression<T> is compiled, is it implicitly cached?编译 Expression<T> 时,它是否被隐式缓存?
【发布时间】:2008-11-03 14:50:04
【问题描述】:

编译Expression&lt;T&gt; 时,生成的代码是否被框架隐式缓存?我正在考虑静态Regex 方法,其中框架隐式编译和缓存最后几个正则表达式。

如果已编译的Expression&lt;T&gt; 对象被缓存,您能否推荐一些最佳做法来降低编译时间或在我手动缓存表达式时可能导致问题的任何陷阱?

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

在这个例子中,我有点担心如果我缓存编译后的表达式,它将使用 arg1arg2 的值,就像它们在编译表达式时一样,而不是检索这些值从堆栈中的适当位置(即,而不是获取当前值)。

【问题讨论】:

    标签: c# .net linq caching expression


    【解决方案1】:

    没有;我不相信它是;如果你想缓存它,你必须保留Delegate 引用(通常是Func&lt;...&gt;Action&lt;...&gt;)。同样,如果您想获得最佳性能,您可以将其编译为参数化表达式,以便在调用它时发送不同的值。

    在这种情况下,重新措辞会有所帮助:

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

    即制作表达式的数字参数,并在运行时传递 实际 个参数(而不是表达式中的常量)。

    【讨论】:

    • 嗨,马克,我从来没有遇到过这种优化。您能否告知这在性能、预编译查询缓存方面是否真的有帮助?
    【解决方案2】:

    Lambda 表达式不会自动缓存。您将需要为此实现自己的缓存/记忆算法。查看相关的 Stackoverflow 问题:

    Is it possible to cache a value evaluated in a lambda expression?

    请务必注意,lambda 表达式在 C# 中是惰性求值的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-20
      • 2011-08-17
      • 2013-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多