我们有包含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();