在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

(编辑)

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


当前回答

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

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

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

其他回答

当你遍历常见的结构如数组、列表等时,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++)

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

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

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

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

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

Patrick Smacchia上个月写了一篇博客,总结如下:

List上的for循环比foreach便宜2倍多一点 循环列表。 在array上循环比在List上循环便宜2倍左右。 因此,使用for对数组进行循环要便宜5倍 而不是使用foreach在List上循环 (我相信,这是我们都在做的事情)。

Jeffrey Richter在techhed 2005上说:

"I have come to learn over the years the C# compiler is basically a liar to me." .. "It lies about many things." .. "Like when you do a foreach loop..." .. "...that is one little line of code that you write, but what the C# compiler spits out in order to do that it's phenomenal. It puts out a try/finally block in there, inside the finally block it casts your variable to an IDisposable interface, and if the cast suceeds it calls the Dispose method on it, inside the loop it calls the Current property and the MoveNext method repeatedly inside the loop, objects are being created underneath the covers. A lot of people use foreach because it's very easy coding, very easy to do.." .. "foreach is not very good in terms of performance, if you iterated over a collection instead by using square bracket notation, just doing index, that's just much faster, and it doesn't create any objects on the heap..."

按需网络直播: http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032292286&EventCategory=3&culture=en-US&CountryCode=US

一种强大而精确的测量时间的方法是使用BenchmarkDotNet库。

在下面的示例中,我在for/foreach上对1,000,000,000个整数记录进行了循环,并使用BenchmarkDotNet进行了测量:

using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;

public class Program
{
    public static void Main()
    {
        BenchmarkRunner.Run<LoopsBenchmarks>();
    }
}

[MemoryDiagnoser]
public class LoopsBenchmarks
{
    private List<int> arr = Enumerable.Range(1, 1_000_000_000).ToList();

    [Benchmark]
    public void For()
    {
        for (int i = 0; i < arr.Count; i++)
        {
            int item = arr[i];
        }
    }

    [Benchmark]
    public void Foreach()
    {
        foreach (int item in arr)
        {
        }
    }
}

结果如下:

结论

在上面的例子中,我们可以看到for循环比foreach循环略快。我们还可以看到两者使用相同的内存分配。