Fer*_*ndo 4 c# performance lambda
我需要将一些信息作为lambda表达式传递给某些方法.基本上,它是一种向数据库查询添加信息的方法.一个简单的例子是:
companyData.GetAll(
where => "SomeField = @SOMEFIELD",
order => "Id",
SOMEFIELD => new Parameter {DbType = DbType.String, Value = "some value"}
)
Run Code Online (Sandbox Code Playgroud)
它工作得很好,除了我需要调用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;
}
}
Run Code Online (Sandbox Code Playgroud)
这个类产生了巨大的差异:从10000次迭代的大约35000毫秒到大约700次.
现在出现了一个问题:我将使用表达式body作为字典的键来遇到什么样的问题?
Jon*_*eet 10
我不清楚为什么你需要表达树,如果你把它们编译成代表.为什么不直接使用委托开始并让编译器将lambda表达式转换为委托而不是表达式树?
至于使用字符串的主体 - 你可能会遇到奇怪的情况,你使用不同的类型,但相同的属性名称.鉴于您已经将类型用作泛型类型参数,但这可能不是问题...我认为它会起作用,尽管我想发誓.
哦,顺便提一句,你的单例缓存不是线程安全的.我建议你instance在静态初始化器中初始化变量.这导致代码更简单,更安全......
private static readonly ExpressionCache<T, U> instance
= new ExpressionCache<T, U>();
public static ExpressionCache<T, U> Instance { get { return instance; } }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3591 次 |
| 最近记录: |