.RemoveAll和.Where之间的性能差异在C#中
我有一个项目列表,我想遍历它们的一个子集。现在,我想知道在从列表中删除不需要的项目之间是否存在性能影响差异,然后通过它循环;或者只是在for循环中过滤列表。.RemoveAll和.Where之间的性能差异在C#中
这里是一个例子。
的removeall过的做法:
list.RemoveAll(o => !someOtherList.Contains(o.Property));
foreach (var i in list)
{
}
在哪里做法:
foreach (var i in list.Where(o => someOtherList.Contains(o.Property))
{
}
据我所知,第一种方法实际上是要处理的是在列表,作为第二个则不会。这并不是真的关心我。我更关心的是第二种方法中的过滤器是否应用于每次迭代,或者C#是否足够聪明以创建子集并且仅循环该子集(几乎就像使用临时变量的第一种方法)。
我更关注是否适用于每个迭代还是C#是足够聪明的创建通过该子集(几乎像第一 方法有 子集,仅环在第二种方法过滤 一个临时变量)
Linq的Where
使用yield为了一次返回一个元素一次请求。
因此,实际上什么是在第二种方法做的是:
1迭代通过列表
2-检查当前的元素相匹配的条件(遍历someOtherList,除非它是一个特殊的查找数据结构如。HashSet
)
3-一旦我们找到的第一个元素返回它
4-执行的foreach体逻辑
5继续从那里我们停在第3步
含义搜索,如果你决定基于在foreach块内部的一些条件打破,那么也许不是所有的列表可以在该点进行扫描,其在某些情况下,可能会在大型列表上提升性能。
谢谢,这很好地解释了它。 – Johannes
作为对其他人已经说过的内容的补充,如果循环操作与您所展示的一样,使用原始性能不会有可忽略的差异。
但是,第一个需要具有物化列表,而后者需要IEnumerable。另外,为了循环内容的运行,首先需要首先实现,直到那时循环内容没有开始完成。使用NOP循环的IOW可能需要大约10秒才能完成某个列表和另一个列表。当循环中有一些工作(可能),那么第一个在进入循环之前花费10秒,那么你需要循环处理的时间。后者OTOH将直接针对找到的每个元素进行循环。如果循环内容是一个耗时的操作,而且可以做到异步,那么后者将是一个明显的赢家。
如果您的问题归结为“someOtherList.Contains'会被调用多少次?”,我强烈怀疑这两个示例的答案是相同的。 –
哪一个更快?运行两次1000次并计算平均值! – user3185569
@Damien_The_Unbeliever:我的问题归结为多少次list.Where将被调用。 – Johannes