LINQ函数的顺序是否重要?

mic*_*ael 113 c# linq performance

基本上,正如问题所述...... LINQ函数的顺序在性能方面是否重要?显然结果仍然必须相同......

例:

myCollection.OrderBy(item => item.CreatedDate).Where(item => item.Code > 3);
myCollection.Where(item => item.Code > 3).OrderBy(item => item.CreatedDate);
Run Code Online (Sandbox Code Playgroud)

两者都返回相同的结果,但是处于不同的LINQ顺序.我意识到重新排序某些项目会产生不同的结果,我并不关心这些.我主要关心的是,在获得相同结果时,排序是否会影响性能.而且,不只是在我做的2个LINQ调用(OrderBy,Where),而是在任何LINQ调用上.

Jon*_*eet 146

它取决于使用的LINQ提供程序.对于LINQ to Objects,这肯定会产生巨大的差异.假设我们实际上得到了:

var query = myCollection.OrderBy(item => item.CreatedDate)
                        .Where(item => item.Code > 3);

var result = query.Last();
Run Code Online (Sandbox Code Playgroud)

这需要对整个集合进行排序,然后进行过滤.如果我们有一百万个项目,其中只有一个项目的代码大于3,那么我们就会浪费大量时间来排序将丢弃的结果.

将其与反向操作进行比较,首先过滤:

var query = myCollection.Where(item => item.Code > 3)
                        .OrderBy(item => item.CreatedDate);

var result = query.Last();
Run Code Online (Sandbox Code Playgroud)

这次我们只是对过滤后的结果进行排序,在"仅与过滤器匹配的单个项目"的示例中,它将在时间和空间上更加高效.

它还可以对查询是否正确执行产生影响.考虑:

var query = myCollection.Where(item => item.Code != 0)
                        .OrderBy(item => 10 / item.Code);

var result = query.Last();
Run Code Online (Sandbox Code Playgroud)

这很好 - 我们知道我们永远不会除以0.但是如果我们在过滤之前执行排序,查询将抛出异常.

  • @michael:你可以在这里找到它http://msmvps.com/blogs/jon_skeet/archive/tags/Edulinq/default.aspx (3认同)
  • @gdoron:说实话,你的意思并不是很清楚.听起来你可能想写一个新问题.请记住,Queryable根本不试图*解释*您的查询 - 它的工作是**仅保留您的查询,以便其他人可以解释它.另请注意,LINQ to Objects甚至不使用表达式树. (3认同)
  • @Jon Skeet,是否有关于每个LINQ提供程序和函数的Big-O的文档?或者这仅仅是"每种表达对于情况都是独特的"的情况. (2认同)
  • @gdoron:重点是这是提供者的工作,而不是 Queryable 的工作。使用实体框架时这也不重要。不过,这对于 LINQ to Objects 确实很重要。但是,是的,无论如何要问另一个问题。 (2认同)

Jer*_*Gee 17

是.

但究竟什么是性能差异取决于如何底层表达式树由LINQ提供评估.

例如,对于LINQ-to-XML,您的查询可能第二次执行得更快(首先使用WHERE子句),但第一次执行LINQ-to-SQL时更快.

要准确了解性能差异,您很可能想要分析您的应用程序.然而,与此类事情一样,过早优化通常不值得付出努力 - 您可能会发现LINQ性能以外的问题更为重要.


Luk*_*keH 5

在您的特定示例中,它可以对性能产生影响.

第一个查询:您的OrderBy调用需要遍历整个源序列,包括Code3或更少的项目.Where然后该子句还需要迭代整个有序序列.

第二个查询:Where调用将序列限制为仅Code大于3的项.然后,OrderBy调用只需要遍历Where调用返回的简化序列.