foreach 比 for 慢 20 倍? [复制]

Posted

技术标签:

【中文标题】foreach 比 for 慢 20 倍? [复制]【英文标题】:foreach 20 times slower than for? [duplicate] 【发布时间】:2019-06-26 13:26:40 【问题描述】:

遍历没有元素的数组或列表,foreach 与 for 相比似乎非常慢。运行下面的代码,我得到的结果是:

3ms 143 毫秒 7 毫秒 foreach 真的很慢还是我做错了什么?

var l = new List<int>();
var watch = new Stopwatch();
var test = 0;

watch.Start();
for (int i = 0; i < 10000000; i++) 
    if (l.Count > 0) 
        test = 1;
watch.Stop();
Debug.Log(watch.ElapsedMilliseconds);

watch.Reset();
watch.Start();
for (int i = 0; i < 10000000; i++) 
    foreach (var item in l) 
        test = 1;
watch.Stop();
Debug.Log(watch.ElapsedMilliseconds);

watch.Reset();
watch.Start();
for (int i = 0; i < 10000000; i++) 
    for (int j = 0; j < l.Count; j++) 
        test = 1;
watch.Stop();
Debug.Log(watch.ElapsedMilliseconds);

【问题讨论】:

抛开任何关于你的时间有效性的问题 - 你正在做某件事一千万次,它需要七分之一秒。这真的有问题吗?你能合理地称之为“真的很慢”吗? 在我的另一个项目中,我经常使用 foreach,而通常被 foreach 编辑的列表没有任何元素。所以我只是想知道是否应该用“for”替换它,或者在 foreach-ing 之前检查列表是否没有元素,以提高性能。 foreach 循环需要使用Enumerator,它有一个Current 属性和MoveNext 方法,每次都会被调用,所以它会更慢。 这是非常具体的情况。 foreach 适用于任何 IEnumerable。只是查看IEnumerable 是否有任何元素将需要获取该对象的枚举器。如果您一直在使用具有可以引用的 Count 的集合,那么该检查可能是有意义的,但是....不,即使那样也不行。不要用类似的东西弄乱你的代码。它只是使它不那么可读。 “为什么他们在迭代之前检查是否有任何元素?!”就像@AakashM 所说,超过 1000 万次迭代所花费的时间仍然只是一眨眼的功夫。只需保持代码干净和 foreach 即可。 总而言之,是的,for 几乎总是foreach 快,至少对于支持恒定时间按索引访问的类型而言。但是,两者都非常快,除非您正在构建一个严重依赖矩阵数学或其他高度专业化用例的应用程序,否则您真的不应该担心它。首先优化可读性,如果有证据表明有必要,再优化性能。 【参考方案1】:

foreach 循环需要使用Enumerator 来迭代集合,这需要访问Current 属性并在每次迭代时调用MoveNext 方法,这需要一些处理时间。

for 循环只需在每次迭代时调用 get_Item,因此这比 foreach 循环少一个调用,这在性能上略有不同。

【讨论】:

而且你必须在迭代结束时调用 Dispose 方法。 基于 using wrap 或其他什么?

以上是关于foreach 比 for 慢 20 倍? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

Linq to objects 比普通 C# 慢 20 倍。有没有办法加快速度?

Google Cloud SQL 很慢:10GB RAM 的 mysql 实例比配置 125MB ram 的 Macbook Pro 慢 20 倍

for、forEach、map的性能对比

前端性能优化:jquery的each为什么比原生的for循环慢很多?

Parallel.ForEach 比 ForEach 慢

实体框架的大批量更新比我自己批量更新慢得多