大型LINQ分组查询,幕后发生了什么

时间:2011-09-12 22:51:20

标签: c# linq foreach group-by parallel-processing

以下面的LINQ查询为例。请不要对代码本身发表评论,因为我只是输入它来帮助解决这个问题。

以下LINQ查询使用“分组依据”并计算摘要信息。正如您所看到的,有许多计算正在对数据执行,但LINQ在幕后的效率如何。

var NinjasGrouped = (from ninja in Ninjas 
    group pos by new { pos.NinjaClan, pos.NinjaRank } 
    into con 
    select new NinjaGroupSummary 
    { 
        NinjaClan = con.Key.NinjaClan, 
        NinjaRank = con.Key.NinjaRank, 
        NumberOfShoes = con.Sum(x => x.Shoes), 
        MaxNinjaAge = con.Max(x => x.NinjaAge), 
        MinNinjaAge = con.Min(x => x.NinjaAge), 
        ComplicatedCalculation = con.Sum(x => x.NinjaGrade) != 0 
        ? con.Sum(x => x.NinjaRedBloodCellCount)/con.Sum(x => x.NinjaDoctorVisits)
        : 0,
    ListOfNinjas = con.ToList() 
    }).ToList(); 
  1. 为了计算每个值而迭代'Ninjas'的列表多少次?
  2. 使用foreach循环加快执行此类查询会更快吗?
  3. 在Ninjas之后添加'.AsParallel()'会导致任何性能提升吗?
  4. 有没有更好的方法来计算List的夏日信息?
  5. 我们赞赏任何建议,因为我们在整个软件中使用这种类型的代码,我真的希望更好地了解LINQ在幕后做什么(可以这么说)。也许有更好的方法?

1 个答案:

答案 0 :(得分:6)

假设这是一个LINQ to Objects查询:

  • Ninjas只迭代一次;这些组被构建到内部具体列表中,然后您将多次迭代(每次聚合一次)。
  • 使用foreach循环几乎肯定不会加快速度 - 你可能会从缓存一致性中受益更多(因为每次迭代一个组时,它可能不得不从更高级别获取数据缓存或主存储器)但我非常怀疑它会很重要。实施它的痛苦增加可能显着,但是:)
  • 使用AsParallel 可能加快速度 - 它看起来很容易并行化。值得一试......
  • 说实话,LINQ to Objects没有更好的方法。能够在分组时执行聚合会很好,而Reactive Extensions允许你做这样的事情,但目前这可能是最简单的方法。

您可能需要查看GroupBy post in my Edulinq blog series,了解有关可能的实施的更多详细信息。