C# LINQ查询性能对比:两种文件排序实现是否等价及优劣分析
首先得提一句:你写的代码2其实有语法错误,OrderBy方法需要传入一个键选择器委托,正确的写法应该是:
var orderedFiles = files.OrderBy(f => new FileInfo(f).LastWriteTime);
我下面就基于这个修正后的代码来分析性能问题。
很明确地说,这两段代码的性能不等价,代码2的实现性能更优,原因主要有这几点:
内存占用差异
代码1的逻辑是先用Select把所有文件路径转换成FileInfo对象,生成一个包含所有FileInfo的中间序列,再对这个序列按LastWriteTime排序。这意味着你需要为所有文件创建FileInfo实例并存储起来,会占用额外的内存空间——而你明确说不需要排序后的列表是FileInfo类型,这部分内存完全是浪费的。代码2则是在排序的键选择器中创建
FileInfo并提取LastWriteTime,LINQ的OrderBy会为每个元素仅计算一次键值并缓存,不会重复创建FileInfo。更重要的是,排序完成后返回的是原文件路径的序列,不需要存储整个FileInfo对象,内存占用更低。不必要的中间操作
代码1的Select是一个额外的中间步骤,虽然LINQ是延迟执行,但当你枚举orderedFiles时,还是会先完成所有FileInfo的创建,再进行排序。而代码2直接将键提取逻辑整合到排序步骤中,没有多余的中间序列生成,执行流程更简洁。后续操作的冗余
如果你最终需要的是文件路径(而非FileInfo),代码1还需要再做一次Select(f => f.FullName)或者映射回原路径的操作,这又会增加一次遍历开销;而代码2直接返回排序后的原路径序列,一步到位。
总结一下:代码2避免了不必要的FileInfo对象存储和中间序列生成,在内存占用和执行效率上都更胜一筹,完全符合你不需要FileInfo类型结果的需求。
内容的提问来源于stack exchange,提问作者Bear Cub

