First()会执行OrderBy()吗?

时间:2010-03-16 14:15:10

标签: linq linq-extensions

之间的(渐近)表现是否有任何差异
var a = Orders.OrderBy(order => order.Date).First()

var y = Orders.Where(order => order.Date == Orders.Min(x => x.Date)).ToList();

即。将First()执行OrderBy()?我猜不是。 MSDN表示通过foreach och GetEnumerator枚举集合,但是短语不排除其他扩展。

4 个答案:

答案 0 :(得分:8)

一些事情:

  • OrderBy()从小到大的订单,所以你的两个选择返回不同的元素
  • Where()通常是懒惰的,所以你的第二个表达式根本不会进行任何计算 - 直到使用它。
  • 原则上,相关行为取决于查询提供程序。例如,您可能确实希望sql-server linq查询提供程序以不同于IEnumerable查询提供程序的方式处理它。查询提供程序可能选择使“OrderBy”的返回值足够专门化,以便在其上调用First()识别(在编译或运行时)它在有序可枚举上运行而不是排序,选择返回(第一个)最小元素。
  • 特别是对于IEnumerable<T>提供程序,OrderBy碰巧返回一个枚举,每次检索第一个元素时都会对输入进行完全缓冲和排序 - 因此,在常见的基本Linq-to-objects情况下,OrderBy().First()OrderBy().ToArray()相当。

记住linq只是一堆函数名 - 每个提供者可能会选择以不同的方式实现它们,所以上面只适用于System.Linq IEnumerable查询提供程序,而不一定适用于其他。

答案 1 :(得分:6)

First将返回传递给它的IEnumerable的第一个条目。由于传递给First的IEnumerable是OrderBy的结果,因此您的问题可以改为“OrderBy是否有效”,是的,是的。

First无法推迟OrderBy的执行,因为它会立即返回结果。例如:

        var numbers = new int[] { 9, 3, 4, 6, 7 };

        var num = numbers.First();
        Console.WriteLine(num);

        num = numbers.OrderBy(i => i).First();
        Console.WriteLine(num);

        Console.ReadLine();

答案 2 :(得分:6)

First方法将执行OrderBy(即,假设当然执行了First方法)。当First方法从OrderBy的结果中提取第一项时,它必须对所有项目进行排序,以找出哪一项是第一项。

根据查询的运行位置和方式(即,如果查询引擎无法围绕它进行优化),第二个查询可能会执行得非常糟糕。如果对Orders.Max中的每个项目评估Orders一次,则会变为O(n * n)操作,这非常糟糕。

还有一个功能上的区别,如果有重复的日期,第二个查询可以返回多个项目。

答案 3 :(得分:0)

没有。这就是SAID - 当然有人试图实际获得第一个元素时,orderby会执行。

但正如你所说,条件可能会进一步明确。因此,不 - 它不会在那一刻执行。