编辑:我看起来更近了一点。WhereEnumerableIterator
扩展方法返回的实际Where
覆盖了该Where
方法并将谓词组合成一个回调。
public override IEnumerable<TSource> Where(Func<TSource, bool> predicate) {
return new Enumerable.WhereEnumerableIterator<TSource>(
this.source,
Enumerable.CombinePredicates<TSource>(this.predicate, predicate));
}
private static Func<TSource, bool> CombinePredicates<TSource>(
Func<TSource, bool> predicate1, Func<TSource, bool> predicate2
) {
return (TSource x) => predicate1(x) && predicate2(x);
}
因此,我在机器上看到的速度差异可能应该归因于其他原因。
第一个示例将遍历elements
集合一次以查找满足条件的项item > 3
,然后再次查找满足条件的项item % 2 == 0
。
第二个示例将遍历elements
集合一次以查找满足条件的项目item > 3 && item % 2 == 0
。
在提供的示例中,第二个很可能总是比第一个快,因为它只循环elements
一次。
这是我在机器(.NET 3.5)上获得的一些非常一致的结果的示例:
var stopwatch = new System.Diagnostics.Stopwatch();
var elements = Enumerable.Range(1, 100000000);
var results = default(List<int>);
stopwatch.Start();
results = elements.Where(n => n > 3).Where(n => n % 2 == 0).ToList();
stopwatch.Stop();
Console.WriteLine(stopwatch.Elapsed);
stopwatch.Reset();
stopwatch.Start();
results = elements.Where(n => n > 3 && n % 2 == 0).ToList();
stopwatch.Stop();
Console.WriteLine(stopwatch.Elapsed);
Console.WriteLine("Done");
Console.ReadLine();
结果:
00:00:03.0932811
00:00:02.3854886
Done
编辑:
@Rawling 是正确的,因为我的解释仅适用于 POCO 对象集合中使用的 LINQ。当用作 LINQ-to-SQL、NHibernate、EF 等的接口时,您的结果将更加依赖于实现。