调用.First()对性能的影响及每个分组的调用次数问题
LINQ
First()方法调用次数与性能影响说明 核心结论
- 你提供的代码中,每个分组会执行4次
First()方法,不存在自动缓存复用的内置优化机制。
C#编译器和LINQ运行时不会自动分析委托内的重复表达式并做结果缓存,每次属性赋值时对应的x.First()调用都会完整执行一次。
不同场景的性能影响
- LINQ to Objects场景:
GroupBy生成的分组会把同组元素存在内存中,单次First()调用只需要取迭代器的第一个元素,开销不算极高,但4次重复调用仍然会产生不必要的计算冗余,当分组数量多、单组元素量大时,浪费会被放大。 - LINQ to 数据库(EF/EF Core等)场景:如果
First()调用没有被查询翻译器识别合并,会为每个分组生成4次独立的首行查询逻辑,严重时会产生N+1类的数据库查询问题,导致IO开销成倍上涨,性能下降明显。
注:你示例代码中Age = x.First()属于笔误,正常应该是取x.First().Age属性。
优化方案
你可以在Select中使用语句Lambda,提前缓存分组首条元素,仅执行1次First()即可完成所有属性赋值:
var result = users .Where(x => x.IsActive) .GroupBy(x => x.City) .Select(x => { // 每个分组仅调用1次First(),结果复用 var firstUser = x.First(); return new MyModel { Name = firstUser.Name, Age = firstUser.Age, CreatingDate = firstUser.CreationDate, HairColor = firstUser.HairColor }; }) .ToArray();
内容的提问来源于stack exchange,提问作者Denis Kaminsky
相关产品推荐
相关产品推荐

