c#中.removeall和.where的性能差异

本文关键字:性能 where removeall | 更新日期: 2023-09-27 18:18:21

我有一个项目列表,我想遍历其中的一个子集。现在,我想知道从列表中删除不需要的项目然后循环它是否会对性能产生影响;或者只是在for循环中过滤列表。

下面是一个例子。

RemoveAll方法:
list.RemoveAll(o => !someOtherList.Contains(o.Property));
foreach (var i in list)
{
}

Where方法:

foreach (var i in list.Where(o => someOtherList.Contains(o.Property))
{
}

我理解第一种方法实际上是要操作列表中的内容,而第二种方法则不会。这与我无关。我更关心的是,第二种方法中的过滤器是否适用于每次迭代,或者c#是否足够聪明,可以创建一个子集,并且只循环遍历该子集(几乎像第一种方法中使用临时变量)。

c#中.removeall和.where的性能差异

我更关心的是第二种方法中的过滤器是否或者c#是否足够聪明,可以创建一个子集,并且只循环遍历该子集(几乎与第一个子集类似)使用临时变量)

的方法

Linq的Where使用yield,以便在请求时一次返回一个元素。

第二种方法实际上是这样做的:

1-遍历列表

2-检查当前元素是否匹配条件(循环someOtherList,除非它是一个特殊的查找数据结构,例如;HashSet)

3-找到第一个元素后返回

4-执行foreach主体逻辑

5-继续从我们在第3步停止的地方搜索

意味着如果你决定基于foreach块内的某些条件中断,那么可能不是所有的列表都可以被扫描,这在某些情况下可能会提高大列表的性能。

作为对其他人已经说过的内容的补充,如果循环操作像您所展示的那样,那么原始性能将不会有可忽略的差异。

但是,前者需要有一个物化的List,而后者使用IEnumerable。此外,要使循环内容运行,首先需要物化一个,直到循环内容开始才完成。对于一些列表和另一些列表,使用NOP循环的ow可能需要大约10秒才能完成。当循环中有一些工作(很可能)时,第一个人在进入循环之前花费了10秒钟,然后您需要在循环中进行处理的时间。后一个OTOH,将直接为它找到的每个元素命中循环。如果循环内容是一个耗时的操作,而且可以异步完成,那么后者将是一个明显的赢家。