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

Bel*_*nda 7 c# linq parallel-processing foreach group-by

以下面的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(); 
Run Code Online (Sandbox Code Playgroud)
  1. 为了计算每个值,"Ninjas"列表被迭代了多少次?
  2. 使用foreach循环加速执行此类查询会更快吗?
  3. 在Ninjas之后添加'.AsParallel()'会导致任何性能提升吗?
  4. 是否有更好的方法来计算List的夏日信息?

任何建议都值得赞赏,因为我们在整个软件中使用这种类型的代码,我真的希望更好地了解LINQ在幕后做什么(可以这么说).也许有更好的方法?

Jon*_*eet 8

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

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

您可能希望查看GroupBy我的Edulinq博客系列中的帖子,了解有关可能实现的更多详细信息.