Linq 在谓词和按子句排序方面非常慢



我们有包含20K对象的List,其中包含日期。我们希望从该列表中找到考虑到一个条件的最新日期。使用如下代码。

listObject.Where(r => r.Date <= asOfDate).OrderByDescending(r => r.Date).FirstOrDefault();

这比预期的要长。 你能帮忙吗? 谢谢!

你可以做(基于@Barns评论(

var maxDate = listObject.Where(r => r.Date <= asOfDate).Max(r => r.date);
var item = listObject.FirstOrDefault(r => r.date == maxDate);

这只会遍历您的列表两次,而不是对其进行排序。

尝试使用Aggregate

listObject
.Where(r => r.Date <= asOfDate)
.Aggregate((acc, curr) => curr.Date > acc.Date ? curr : acc)

在性能方面,它可以改进在Aggregate内部移动过滤逻辑,并在内部引入具有空处理的零累加器,但如果性能是一个大问题,只需切换到for循环。

您目前有三个操作:

.Where(r => r.Date <= asOfDate)- 时间复杂度 O(n(

.OrderByDescending(r => r.Date)- 时间复杂度(我想象( O(n log(n((

.FirstOrDefault();- 时间复杂度 O(0(

您可以执行以下操作并获得相同的结果:

var maxDate= listObject.Where(r => r.Date <= asOfDate).Max(r => r.date);- 时间复杂度 O(n(

var result = listObject.FirstOrDefault(r => r.Date == maxDate);- 时间复杂度 O(n(

为什么不像这样组合 Where 和 Max 操作:

var maxDate = listObject.Max(r => r.Date <= asOfDate ? r.Date : DateTime.MinValue);
var item = listObject.FirstOrDefault(r => r.date == maxDate);

这只会在列表中运行两次。

您是否先尝试过对集合进行排序?

listObject
.OrderByDescending(ordr => ordr.Date)
.Where(obj => obj.Date <= asOfDate)
.FirstOrDefault();

最新更新