C# 使用linq更新对象的性能更好
我有两个自定义对象列表,如果另一个列表中有一个对象与另一对字段匹配,我想为一个列表中的所有对象更新一个字段 这段代码更好地解释了这个问题,并产生了我想要的结果。但是,对于较大的20k列表和具有匹配对象的20k列表,这需要相当长的时间(31s)。通过使用泛型列表查找(谓词)方法,我可以提高50%C# 使用linq更新对象的性能更好,c#,linq,performance,optimization,linq-to-objects,C#,Linq,Performance,Optimization,Linq To Objects,我有两个自定义对象列表,如果另一个列表中有一个对象与另一对字段匹配,我想为一个列表中的所有对象更新一个字段 这段代码更好地解释了这个问题,并产生了我想要的结果。但是,对于较大的20k列表和具有匹配对象的20k列表,这需要相当长的时间(31s)。通过使用泛型列表查找(谓词)方法,我可以提高50% 所以我的问题是,是否有可能像我使用T-SQL那样做一些事情?在调整值上使用ISNULL(val,0)从左连接进行更新。该连接应该相当快,因为它将首先循环通过所有adjList创建查找,然后对于propLi
所以我的问题是,是否有可能像我使用T-SQL那样做一些事情?在调整值上使用ISNULL(val,0)从左连接进行更新。该连接应该相当快,因为它将首先循环通过所有
adjList
创建查找,然后对于propList
中的每个元素,它将只使用查找。在更大的代码中,这比O(N*M)方法要快——尽管在循环之前通过调用adjList
可以很容易地解决(或者只需要一个值)
编辑:下面是使用ToDictionary
修改的代码。未经测试,请注意
var adjDictionary = adjList.ToDictionary(av => av.PropName);
foreach (var p in propList)
{
Adjustment a;
if (adjDictionary.TryGetValue(p.Name, out a))
{
p.Total = p.Val + a.AdjVal;
}
else
{
p.Total = p.Val;
}
}
如果adjList可能有重复的名称,则应在推送到字典之前对项目进行分组
Dictionary<string, decimal> adjDictionary = adjList
.GroupBy(a => a.PropName)
.ToDictionary(g => g.Key, g => g.Sum(a => a.AdjVal))
propList.ForEach(p =>
{
decimal a;
adjDictionary.TryGetValue(p.Name, out a);
p.Total = p.Val + a;
});
Dictionary adjDictionary=adjList
.GroupBy(a=>a.PropName)
.ToDictionary(g=>g.Key,g=>g.Sum(a=>a.AdjVal))
propList.ForEach(p=>
{
十进制a;
TryGetValue(p.Name,out a);
p、 总计=p.Val+a;
});
我知道我发这篇文章晚了,但我想有人会喜欢下面更清晰、更简短的答案,它可以处理adjList中每次查找的多个记录。创建查找将允许对多个项目进行快速查找,如果查找中没有记录,将返回空列表
var adjLookUp = adjList.ToLookUp(a => a.PropName);
foreach (var p in propList)
p.Total = p.Val + adjLookUp[p.Name].Sum(a => a.AdjVal);
谢谢你的快速回复!我最近开始研究linq,并尝试在代码中很难模仿t-sql。您未经测试的代码以ms度量,因此我得到了我要求的性能提升。很高兴它有帮助。。。虽然我不确定为什么这个问答现在是一个社区维基:(发布时有一个“社区维基”复选框。有时它被启用,即使你从未单击过它。奇怪。我知道有其他触发器可以自动将某个东西设为维基,但这听起来像是一个基本错误:(
Dictionary<string, decimal> adjDictionary = adjList
.GroupBy(a => a.PropName)
.ToDictionary(g => g.Key, g => g.Sum(a => a.AdjVal))
propList.ForEach(p =>
{
decimal a;
adjDictionary.TryGetValue(p.Name, out a);
p.Total = p.Val + a;
});
var adjLookUp = adjList.ToLookUp(a => a.PropName);
foreach (var p in propList)
p.Total = p.Val + adjLookUp[p.Name].Sum(a => a.AdjVal);