之间的(渐近)性能是否有任何差异
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 枚举集合确实如此,但措辞并不排除其他扩展。
之间的(渐近)性能是否有任何差异
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 枚举集合确实如此,但措辞并不排除其他扩展。
一些东西:
OrderBy()
订单从小到大,因此您的两种选择返回不同的元素Where()
通常是懒惰的,因此您的第二个表达式实际上根本不进行任何计算 - 直到使用。First()
它可以识别(在编译或运行时)它在有序枚举上运行,而不是排序,选择返回(第一个) 最小元素。IEnumerable<T>
提供者,OrderBy
碰巧在每次检索第一个元素时返回一个完全缓冲和排序输入的可枚举 - 因此,在常见的基本 Linq-to-objects 情况下,OrderBy().First()
可与OrderBy().ToArray()
.请记住,linq 只是一堆函数名称 - 每个提供者可能会选择以不同的方式实现它们,因此上述内容仅适用于 System.Linq IEnumerable 查询提供者,不一定适用于其他提供者。
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();
该First
方法将执行OrderBy
(即,First
当然,假设该方法已执行)。当该First
方法从 的结果中提取第一项时OrderBy
,它必须对所有项进行排序以找出哪个是第一项。
根据查询的运行位置和方式(即,如果查询引擎无法围绕它进行优化),第二个查询可能会执行得非常糟糕。如果Orders.Max
对 中的每个项目都进行一次评估Orders
,则它变成了 O(n*n) 操作,这非常糟糕。
还有一个功能差异,如果有重复的日期,第二个查询可以返回多个项目。
它不是。话虽这么说 - 当然,orderby 将在有人尝试实际获取第一个元素的那一刻执行。
但正如你所说,条件可能会进一步定义。因此,不 - 它在那一刻不执行。