You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Lambda表达式的Where子句中使用Select是否存在性能损耗?

三种写法的性能差异分析

你的假设完全正确,第一种写法和第三种写法的性能完全不一致,第三种的性能远优于前两种,具体原因如下:

第一种写法的性能问题

var eventsToBeCreated = 
    requiredEventDates.Where(d => !events.Select(e => e.eventDay).Contains(d));

在这个写法里,Where的每个元素判断逻辑都会完整执行一遍events.Select(e => e.eventDay),再调用Contains遍历这个新生成的序列。假设requiredEventDates有M个元素,events有N个元素,那么总操作次数是M*N——每检查一个日期,就要重新遍历一次所有事件提取日期,再遍历这个临时序列做匹配。数据量越大,性能下降越明显。

第二种写法的本质问题

如果你只是提前定义IEnumerable<DateTime> existingEventDays = events.Select(e => e.eventDay);,再用Where(d => !existingEventDays.Contains(d)),性能和第一种几乎没有区别。因为IEnumerable是延迟执行的,每次调用Contains时,都会重新触发Select的逻辑,再次遍历events生成日期序列,本质还是重复执行了M次Select+遍历。

第三种写法的性能优势

var existingEventDays = events.Select(e => e.eventDay).ToList();
var eventsToBeCreated = requiredEventDates.Where(d => !existingEventDays.Contains(d));

调用ToList()后,会立即执行Select逻辑并将结果缓存到List集合中。后续的Contains判断只会在这个已缓存的List里做线性查找,而不会再去遍历原始的events集合。总操作次数变成N + M*K(K是List的平均查找长度,远小于N),性能提升非常显著。

额外优化建议

如果events的数量很大,还可以把ToList()换成ToHashSet():

var existingEventDays = events.Select(e => e.eventDay).ToHashSet();

HashSet的Contains操作是O(1)的时间复杂度,能进一步降低查找开销,适合处理大规模数据集合。

内容的提问来源于stack exchange,提问作者Patric

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 22:35:09