gpt4 book ai didi

c# - 缓存已编译的 lambda 表达式

转载 作者:太空狗 更新时间:2023-10-29 23:57:53 25 4
gpt4 key购买 nike

我需要将一些信息作为 lambda 表达式传递给某些方法。基本上,这是一种向数据库查询添加信息的方法。一个简单的例子是:

companyData.GetAll(
where => "SomeField = @SOMEFIELD",
order => "Id",
SOMEFIELD => new Parameter {DbType = DbType.String, Value = "some value"}
)

它工作得很好,除了我需要调用 LambdaExpression.Compile获取对性能有很大影响的参数对象。

为了获得更快的结果,我提供了这个简单的缓存测试:
class ExpressionCache<T,U>
{

private static ExpressionCache<T, U> instance;
public static ExpressionCache<T, U> Instance
{
get
{
if (instance == null) {
instance = new ExpressionCache<T, U>();
}
return instance;
}
}

private ExpressionCache() { }

private Dictionary<string, Func<T, U>> cache = new Dictionary<string, Func<T, U>>();

public Func<T, U> Get(Expression<Func<T, U>> expression)
{
string key = expression.Body.ToString();
Func<T,U> func;
if (cache.TryGetValue(key, out func)) {
return func;
}
func = expression.Compile();
cache.Add(key, func);
return func;
}
}

这个类产生了巨大的差异:从 10000 次迭代的大约 35000 毫秒到大约 700 次。

现在问题来了:使用表达式主体作为字典的键我会遇到什么样的问题?

最佳答案

如果您将表达式树编译为委托(delegate),我不清楚为什么您需要表达式树。为什么不直接使用委托(delegate)开始并让编译器将 lambda 表达式转换为委托(delegate)而不是表达式树?

至于使用字符串的主体 - 您可能会遇到使用不同类型但属性名称相同的奇怪情况。但是,鉴于您已经将类型用作泛型类型参数,这可能不是问题......我应该认为它会起作用,尽管我想发誓。

哦,顺便说一下,你的单例缓存不是线程安全的。我建议你初始化 instance静态初始化器中的变量。这导致更简单的代码以及更安全......

private static readonly ExpressionCache<T, U> instance
= new ExpressionCache<T, U>();
public static ExpressionCache<T, U> Instance { get { return instance; } }

关于c# - 缓存已编译的 lambda 表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1461809/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com