繁体   English   中英

Linq 使用谓词和 order by 子句非常慢

[英]Linq is very slow with predicate and order by clause

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

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内移动过滤逻辑并引入 null 内部处理的 null 累加器,但如果性能是一个大问题,只需切换到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();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM