转换IEnumerable<T>内元素的最快方式?LINQ Select性能表现疑问
核心原因:LINQ的延迟执行特性
你测到的Select操作0ms不是什么性能黑科技,就是LINQ的*延迟执行(惰性求值)*特性:Select 方法本身只会构造一个迭代器对象,不会立刻执行你写的转换逻辑,所有的new Point、数值计算逻辑,都会等到你第一次遍历这个迭代器(比如用foreach遍历、调用ToList/ToArray、访问元素)的时候才会实际执行。
关于重复计算的问题
对,如果你不把Select的结果物化(转成List/Array等集合存起来),每次遍历都会重新执行一遍所有转换逻辑:
- 如果你后续只需要遍历一次这个转换后的序列,不会重复访问,那直接用
Select返回的迭代器完全没问题,总计算量和foreach方案一致,不会有额外开销,反而不需要提前占用内存存所有转换后的元素,适合流式处理场景。 - 如果你后续需要多次访问序列元素、需要按下标随机访问、需要提前获取序列长度,那重复计算的开销会非常明显,这种场景必须把结果物化存起来。
性能优化方案
不同场景选不同方案即可:
- 单次遍历场景:直接用不转List的
Select方案即可,没有额外问题,总耗时和foreach方案一致。 - 多次访问/随机访问场景:
- 对性能要求不高的话,直接
Select(...).ToList()就行,和直接foreach的性能差距非常小,完全可以接受。 - 极致性能优化的话,可以提前获取原序列的长度,预分配List的容量避免扩容开销,代码示例:
这种写法比// 提前获取原序列长度,预分配容量 var result = new List<Point>(Initial.Count()); foreach (var p in Initial) { result.Add(new Point(p.Price * p.Quantity, 1 / p.Price)); }Select().ToList()略快,因为省去了LINQ迭代器的额外开销,也避免了List动态扩容的性能损耗。 - 对性能要求不高的话,直接
性能测试注意事项
你之前的测试方法是不准确的,测试LINQ操作的性能时,必须把枚举执行的过程包含在计时范围内,否则测到的只是迭代器构造的时间,没有参考价值。
内容的提问来源于stack exchange,提问作者samuel guedon
相关产品推荐
相关产品推荐

