为何C#中嵌套foreach循环性能远超SelectMany+foreach及GroupBy?
为什么嵌套foreach循环的性能比另外两种LINQ实现更优?
现有模型类
public class BenchMarks{ public List<Parent> Parents { get; set; } } public class Parent { public List<Child> Children { get; set; } } public class Child { public string Name { get; set; } public int Value { get; set; } }
BenchMarks类包含的三种实现方法
public void GetWithTwoForeach(){ var dict = new Dictionary<string,int>(); foreach(var parent in Parents){ foreach(var child in parent.Children){ if (dict.ContainsKey(child.Name)) dict[child.Name] += child.Value; else dict.Add(child.Name, child.Value); } } } public void GetWithOneForeach(){ var dict = new Dictionary<string,int>(); foreach(var child in Parents.SelectMany(p=>p.Children)){ if (dict.ContainsKey(child.Name)) dict[child.Name] += child.Value; else dict.Add(child.Name, child.Value); } } public void GetWithGroupSum(){ var childGroups = Parents.SelectMany(p=>p.Children).GroupBy(c => c.Name); var dict = childGroups.ToDictionary(cg => cg.Key, cg => cg.Sum(child => child.Value)); }
问题
为何嵌套foreach循环的性能比另外两种方法高出100%以上?(首次基准测试结果显示嵌套foreach性能是另外两种方法的2倍以上)
编辑补充
此前的基准测试受测试数据有序性影响,修改测试数据初始化逻辑后,性能差距有所缩小,但嵌套foreach仍比LINQ实现有明显性能优势。
修改后的测试数据初始化代码
public void Setup() { Parents = new List<Parent>(); var names = new List<string>{"Tigo","Edo","Kumal","Manu","Guido","Anne","Steff","Mimi","Suzan","Jeff"}; var random = new Random(); for (var i = 0; i < 200; i++) { int index = random.Next(names.Count); Parents.Add(new Parent { Children = new List<Child> { new Child { Name = names[index], Value = i } } }); } }
调整后基准测试显示性能差距缩小,但LINQ实现仍存在可观测的性能开销。
性能差异的原因分析
LINQ的额外对象与委托开销
SelectMany、GroupBy这类LINQ方法会创建迭代器对象(如SelectManyIterator、GroupedEnumerable),这些对象的分配和回收会增加GC压力;同时LINQ中的Lambda表达式本质是委托调用,每次迭代都会多一层调用栈开销,累积后影响性能。而嵌套foreach直接遍历原生集合,没有这些额外开销。GroupBy的双重遍历成本
GetWithGroupSum方法中,GroupBy需要先遍历所有Child完成分组,之后Sum又要对每个分组内的元素再次遍历求和,相当于对Child元素做了两次完整遍历;而嵌套foreach只遍历一次Child就完成累加,遍历次数更少。JIT优化的差异
嵌套foreach是直白的循环结构,JIT编译器可以对其进行充分优化,比如循环展开、边界检查消除等;而LINQ的迭代器模式结构复杂,JIT难以做到同等程度的优化,部分优化会被迭代器的封装逻辑阻断。
内容的提问来源于stack exchange,提问作者Daniël Tulp
相关产品推荐
相关产品推荐

