结合LINQ语句以提高效率

时间:2010-02-02 22:29:18

标签: c# linq performance where-clause

关于linq到对象,如果我使用.Where(x => x ....)然后直接使用.SkipWhile(x => x ...)这会导致性能下降,因为我要经过两次收藏?

我是否应该找到将所有内容放在Where子句或SkipWhile子句中的方法?

5 个答案:

答案 0 :(得分:7)

由于将迭代器链接在一起会导致轻微的低效率,但它确实会非常小。 (特别是,尽管两个运营商都会看到每个匹配的项目,但它们不会被缓冲或类似的任何东西.LINQ to Object不会创建所有匹配项目的新列表,而在它上面运行SkipWhile。)

如果 性能至关重要,那么首先不使用LINQ可能会导致轻微的速度提升。在所有其他情况下,首先编写最简单的代码,只有在证明它是瓶颈时才会担心这样的微优化。

答案 1 :(得分:2)

与大多数事情一样,答案取决于你在做什么。如果您在同一个对象上有多个操作位置,那么可能值得将它们与&&&'s组合起来。

大多数LINQ运算符不会遍历每个运算符的整个集合,它们只处理一个项目并将其传递给下一个运算符。这有例外,例如Reverse和OrderBy,但通常如果您使用Where和SkipWhile,那么您将拥有一个可以一次处理一个项目的链。现在你的第一个Where语句显然可以过滤掉一些项目,所以SkipWhile在通过前面的运算符之前不会看到一个项目。

我个人的偏好是为了清晰起见将操作员分开,只有在性能成为问题时才将它们合并。

答案 2 :(得分:2)

使用Where和SkipWhile不会导致“经过两次收集”。 LINQ to Objects适用于拉模型。当您枚举组合查询时,SkipWhile将开始询问其元素来源。它的来源是Where,所以这将导致Where开始依次询问它的来源元素。所以SkipWhile将会看到所有传递Where子句的元素,但是它会随着它而变化。结果是LINQ对原始集合进行了预测,只返回通过Where和SkipWhile过滤器的元素 - 这只涉及到集合的一次传递。

可能存在微不足道的效率损失,因为涉及两个迭代器,但它不太可能是重要的。您应该编写清晰的代码(正如您目前所做的那样),如果您怀疑清晰版本导致性能问题,测量以确保,然后尝试合并条款。

答案 3 :(得分:2)

当您使用WhereSkipWhile时, 不会两次遍历该集合。

Where方法一次将其输出流式传输到SkipWhile方法一个项目,同样SkipWhile方法将其输出流式传输到任何后续方法一次一个项目

(由于编译器会在幕后为每个方法生成单独的迭代器对象,因此开销很小。但如果我担心编译器生成的迭代器的开销,那么我可能不会首先使用LINQ 。)

答案 4 :(得分:1)

不,(基本上)没有性能损失。这就是懒惰(延迟)执行的全部内容。