OrderBy().Last() or OrderByDescending().First() performance

本文关键字:First performance OrderByDescending Last OrderBy or | 更新日期: 2023-09-27 18:01:53

我知道这可能是微优化,但我仍然想知道使用

是否有任何区别
var lastObject = myList.OrderBy(item => item.Created).Last();

var lastObject = myList.OrderByDescending(item => item.Created).First();

我正在寻找Linq到对象和Linq到实体的答案。

OrderBy().Last() or OrderByDescending().First() performance

假设两种排序方法花费的时间相等(这是一个很大的"如果"),那么第一种方法将有执行.Last()的额外成本,可能需要完整的枚举。

对于面向SQL的LINQ来说,这个参数可能更有效。

(我的回答是关于Linq到对象,而不是Linq到实体)

我不认为这两个指令之间有很大的区别,这显然是一个微优化的例子。在这两种情况下,都需要对集合进行排序,这通常意味着复杂度为O(n log n)。但是,通过枚举集合并跟踪最小值或最大值,您可以轻松地以O(n)的复杂度获得相同的结果。Jon Skeet在他的MoreLinq项目中以MaxBy扩展方法的形式提供了一个实现:

var lastObject = myList.MaxBy(item => item.Created);

很抱歉我不能直接回答你的问题,但是…

为什么不做一个更好的优化,使用Jon Skeet的MaxBy或MinBy实现?

这将是O(n)而不是O(n log n)在你给出的两个替代方案中

这两种情况都取决于您的底层集合。如果您在订购和选择之前预先了解集合的外观,则可以选择其中一个而不是另一个。例如,如果您知道列表通常以升序(或主要是升序)排序,则可以选择第一个选择。或者如果您知道SQL表上的索引是升序排序的。尽管SQL优化器可能可以处理这个问题。

在一般情况下,它们是等价语句。当你说这是微优化时,你是对的。

假设OrderBy和orderbydescent的平均性能相同,当元素数量较大时,取第一个元素将比最后一个元素执行得更好。

只是我的两分话:因为OrderByOrderByDescending必须遍历所有对象,所以应该没有区别。然而,如果是我,我可能只是循环遍历foreach中的所有项目,并进行比较以保存最高的比较项目,这将是一个O(n)搜索,而不是排序的数量级。

为了给出一个更新的答案(因为。net是一个不断发展的生态系统),在。net 6中引入了以下内容

https://learn.microsoft.com/en us/dotnet/api/system.linq.enumerable.maxby?view=net - 6.0

对于你的问题

var lastObject = myList.OrderBy(item => item.Created).Last();

会变成

var lastObject = myList.MaxBy(item => item.Created);

O(n)时间执行