11

之间的(渐近)性能是否有任何差异

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

4 回答 4

11

一些东西:

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

请记住,linq 只是一堆函数名称 - 每个提供者可能会选择以不同的方式实现它们,因此上述内容仅适用于 System.Linq IEnumerable 查询提供者,不一定适用于其他提供者。

于 2010-03-16T14:45:18.600 回答
6

First将返回传递给它的 IEnumerable 的第一个条目。由于传递给的 IEnumerableFirst是您的问题的结果,因此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();
于 2010-03-16T14:21:04.757 回答
6

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

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

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

于 2010-03-16T14:24:42.300 回答
0

它不是。话虽这么说 - 当然,orderby 将在有人尝试实际获取第一个元素的那一刻执行。

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

于 2010-03-16T14:19:47.753 回答