Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用linq更新对象的性能更好_C#_Linq_Performance_Optimization_Linq To Objects - Fatal编程技术网

C# 使用linq更新对象的性能更好

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

我有两个自定义对象列表,如果另一个列表中有一个对象与另一对字段匹配,我想为一个列表中的所有对象更新一个字段

这段代码更好地解释了这个问题,并产生了我想要的结果。但是,对于较大的20k列表和具有匹配对象的20k列表,这需要相当长的时间(31s)。通过使用泛型列表查找(谓词)方法,我可以提高50%


所以我的问题是,是否有可能像我使用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);