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到实体的答案。
假设两种排序方法花费的时间相等(这是一个很大的"如果"),那么第一种方法将有执行.Last()
的额外成本,可能需要完整的枚举。
(我的回答是关于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的平均性能相同,当元素数量较大时,取第一个元素将比最后一个元素执行得更好。
只是我的两分话:因为OrderBy
或OrderByDescending
必须遍历所有对象,所以应该没有区别。然而,如果是我,我可能只是循环遍历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)
时间执行