[英]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.