在c# / VB.NET/。哪个循环运行得更快,for还是foreach?

自从很久以前我读到for循环比foreach循环工作得快,我就认为它适用于所有集合、泛型集合、所有数组等。

我搜索了谷歌,找到了几篇文章,但大多数都是不确定的(阅读文章评论),而且是开放式的。

理想的情况是列出每种情况以及最佳解决方案。

例如(这只是一个例子):

用于迭代1000+的数组 字符串- for比foreach好 对于迭代IList(非泛型)字符串- foreach更好 比

在网上找到了一些相同的参考资料:

由Emmanuel Schanzer撰写的原创文章 CodeProject FOREACH Vs. FOR 博客——去博客还是不去博客,这是个问题 ASP。NET论坛- NET 1.1 c# for vs foreach

(编辑)

除了可读性之外,我对事实和数据真的很感兴趣。在某些应用中,最后一英里的性能优化确实很重要。


当前回答

在我的Windows Mobile项目中,我为控件集合使用了for循环。20个控制需要100毫秒!foreach循环只使用了4毫秒。这是一个性能问题……

其他回答

两者的运行方式几乎完全相同。编写一些代码来使用两者,然后向他展示IL。它应该显示类似的计算,这意味着在性能上没有差异。

我认为在大多数情况下,for比foreach稍微快一点,但这真的没有抓住重点。有一件事我没有看到提到的是,在你正在谈论的场景中(即,一个大容量的web应用程序),for和foreach之间的性能差异对站点的性能没有影响。你将受到请求/响应时间和DB时间的限制,而不是v. foreach。

也就是说,我不理解你对foreach的厌恶。在我看来,foreach在任何一个都可以使用的情况下通常更清楚。我通常为需要以某种丑陋的、非标准的方式遍历集合的情况而保留。

有很好的理由选择foreach循环而不是for循环。如果你可以使用foreach循环,你的老板说你应该这样做是对的。

然而,并不是每次迭代都是简单地按顺序逐个遍历列表。如果他是禁止的,是的,那是错误的。

如果我是你,我会把你所有的for循环转化成递归。这样可以教会他,对你来说也是很好的脑力锻炼。

这和大多数“哪个更快”的问题有相同的两个答案:

1)如果你不测量,你就不知道。

2)(因为…)视情况而定。

这取决于“MoveNext()”方法的代价,相对于“this[int index]”方法的代价,对于你要迭代的IEnumerable的类型(或类型)。

“foreach”关键字是一系列操作的简写——它在IEnumerable上调用GetEnumerator()一次,每次迭代调用MoveNext()一次,它做一些类型检查,等等。最可能影响性能度量的是MoveNext()的成本,因为它被调用了O(N)次。可能便宜,但也可能不便宜。

“for”关键字看起来更容易预测,但在大多数“for”循环中,你会发现类似“collection[index]”这样的东西。这看起来像是一个简单的数组索引操作,但它实际上是一个方法调用,其开销完全取决于迭代的集合的性质。可能便宜,但也可能不便宜。

如果集合的底层结构本质上是一个链表,MoveNext是非常便宜的,但是索引器可能有O(N)成本,使得“for”循环的真正成本为O(N*N)。

当你遍历常见的结构如数组、列表等时,for-和foreach-循环的速度差异很小,并且在集合上执行LINQ查询几乎总是稍微慢一些,尽管它写得更好!正如其他海报上说的那样,追求表现力而不是多出一毫秒的性能。

到目前为止还没有说的是,当编译foreach循环时,编译器会根据它迭代的集合对它进行优化。这意味着当你不确定使用哪个循环时,你应该使用foreach循环——它会在编译时为你生成最好的循环。它的可读性也更强。

foreach循环的另一个关键优势是,如果你的集合实现发生了变化(例如,从int数组到List<int>),那么你的foreach循环将不需要任何代码更改:

foreach (int i in myCollection)

不管你的集合是什么类型,上面的都是一样的,而在你的for循环中,如果你把myCollection从数组改变为List,下面的将不会构建:

for (int i = 0; i < myCollection.Length, i++)