在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

(编辑)

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


当前回答

每种语言结构都有适当的使用时间和地点。c#语言有四个单独的迭代语句是有原因的——每个语句都有特定的目的,并且有适当的用法。

我建议你和你的老板坐下来,试着理性地解释为什么for循环有一个目的。有时for迭代块比foreach迭代块更清楚地描述算法。在这种情况下,使用它们是合适的。

我还要向你的老板指出——性能不是,也不应该是任何实际方式的问题——这更像是用简洁、有意义、可维护的方式表达算法的问题。这样的微优化完全忽略了性能优化的要点,因为任何真正的性能好处都来自算法重新设计和重构,而不是循环重构。

如果在理性的讨论之后,仍然有这种权威主义的观点,那就取决于你如何继续下去了。就我个人而言,我不会喜欢在一个不鼓励理性思考的环境中工作,我会考虑跳槽到另一个雇主手下。然而,我强烈建议在感到不安之前讨论一下——这可能只是一个简单的误解。

其他回答

两者之间不太可能有巨大的性能差异。与往常一样,当面对“哪个更快?”的问题时,您应该始终认为“我可以测量这个”。

在循环体中编写两个做相同事情的循环,执行并计时,并查看速度的差异。使用一个几乎为空的主体和一个与您实际要做的类似的循环主体来执行此操作。还可以尝试使用您正在使用的集合类型,因为不同类型的集合可能具有不同的性能特征。

我遇到了一个案子,foreach比For快得多

为什么foreach在读取richtextbox行时比for循环快

我有一个类似于那个问题中的OP的案例。

A textbox reading about 72K lines, and I was accessling the Lines property(which is actually a getter method). (And apparently often in winforms there are getter methods that aren't O(1). I suppose it's O(n), so the larger the textbox the longer it takes to get a value from that 'property'. And in the for loop I had as the OP there had for(int i=0;i<textBox1.lines.length;i++) str=textBox1.Lines[i] , and it was really quite slow as it was reading the entire textbox each time it read a line plus it was reading the entire textbox each time it checked the condition.

Jon Skeet演示了您可以只访问一次Lines属性(甚至不是每次迭代一次,只是一次)。而不是每次迭代两次(这是大量的次数)。Do string[] strarlines = textBox1.Lines;然后在星线间循环。

但是一个直观形式的for循环访问Lines属性是非常低效的

for (int i = 0; i < richTextBox.Lines.Length; i++)
{
    s = richTextBox.Lines[i];
}

对于文本框,或者富文本框,它非常慢。

OP在一个富文本框上测试了这个循环,发现“有15000行。For循环花了8分钟才循环到15000行。而foreach只花了不到一秒钟的时间来列举它。”

那个链接的OP发现这个foreach比上面提到的他(同一个OP)的for循环要有效得多。就像我一样。

   String s=String.Empty;
   foreach(string str in txtText.Lines)
    {
       s=str;
    }

for是否比foreach快确实不是重点。我非常怀疑选择其中之一会对你的表现产生重大影响。

优化应用程序的最佳方法是对实际代码进行分析。这将精确地找出占用最多工作/时间的方法。首先优化它们。如果性能仍然不能接受,请重复上述步骤。

一般来说,我建议不要进行微观优化,因为它们很少会产生任何显著的收益。唯一的例外是在优化确定的热门路径时(即,如果您的分析确定了一些高度使用的方法,那么广泛地优化这些方法可能是有意义的)。

我不期望任何人发现两者之间的“巨大”性能差异。

我想答案取决于您试图访问的集合是否具有更快的indexer访问实现或更快的IEnumerator访问实现。由于IEnumerator经常使用索引器,并且仅保存当前索引位置的副本,因此我希望枚举器访问至少与直接索引访问一样慢或更慢,但不会慢太多。

当然,这个答案没有解释编译器可能实现的任何优化。

Foreach循环比for循环展示了更具体的意图。

使用foreach循环向使用您代码的任何人表明,您计划对集合中的每个成员执行一些操作,而不管其在集合中的位置。它还显示您没有修改原始集合(如果您试图修改,则会抛出异常)。

foreach的另一个优点是它适用于任何IEnumerable,而as for只适用于IList,其中每个元素实际上都有一个索引。

但是,如果需要使用元素的索引,那么当然应该允许使用for循环。但是如果您不需要使用索引,那么使用索引只会使您的代码变得混乱。

据我所知,这对性能没有重大影响。在未来的某个阶段,使用foreach调整代码以在多核上运行可能会更容易,但现在还不需要担心这一点。