为什么LINQ .Where(谓词).First()比.First(谓词)快?

时间:2011-12-29 04:07:32

标签: c# .net performance linq

我正在做一些性能测试,并注意到像

这样的LINQ表达式
result = list.First(f => f.Id == i).Property

慢于

result = list.Where(f => f.Id == i).First().Property

这似乎反直觉。我原以为第一个表达式会更快,因为它可以在谓词满足后立即停止遍历列表,而我会认为.Where()表达式可能会在调用{{}之前遍历整个列表。 1}}在结果子集上。即使后者发生短路,它也不应该比直接使用First更快,但它确实如此。

下面是两个非常简单的单元测试来说明这一点。在TestWhereAndFirst上进行优化编译时,比.Net和Silverlight 4上的TestFirstOnly快30%。我尝试使谓词返回更多结果,但性能差异是相同的。

任何人都可以解释为什么.First().First(fn)慢?与.Where(fn).First()相比,.Count(fn)我看到一个类似的反直觉结果。

.Where(fn).Count()

1 个答案:

答案 0 :(得分:47)

我得到了相同的结果:第一个比第一个更快。

正如Jon指出的那样,Linq使用惰性评估,因此两种方法的性能应该(并且是)大致相似。

查看Reflector,First使用一个简单的foreach循环来遍历集合,但Where有各种迭代器专门用于不同的集合类型(数组,列表等)。据推测,这就是给予小优势的地方。