在。net中,哪个循环运行得更快,“for”还是“foreach”?

时间:2022-02-27 02:56:21

In C#/VB.NET/.NET, which loop runs faster, for or foreach?

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

Ever since I read that a for loop works faster than a foreach loop a long time ago I assumed it stood true for all collections, generic collections, all arrays, etc.

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

I scoured Google and found a few articles, but most of them are inconclusive (read comments on the articles) and open ended.

我搜索了谷歌,发现了一些文章,但大多数都不是结论性的(请参阅文章评论),而且是开放式结尾的。

What would be ideal is to have each scenario listed and the best solution for the same.

理想的情况是将每个场景都列出,并且最好的解决方案是相同的。

For example (just an example of how it should be):

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

  1. for iterating an array of 1000+ strings - for is better than foreach
  2. 对于迭代1000+字符串数组,for比foreach更好。
  3. for iterating over IList (non generic) strings - foreach is better than for
  4. 对于迭代IList(非泛型)字符串—foreach比for好。

A few references found on the web for the same:

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

  1. Original grand old article by Emmanuel Schanzer
  2. 伊曼纽尔·尚策(Emmanuel Schanzer)的《古老的伟大》(grand old article)
  3. CodeProject FOREACH Vs. FOR
  4. CodeProject上FOREACH与对
  5. Blog - To foreach or not to foreach, that is the question
  6. 博客-为每个人或不为每个人,这是一个问题
  7. ASP.NET forum - NET 1.1 C# for vs foreach
  8. ASP。NET论坛- NET 1.1 c#为vs foreach

[Edit]

(编辑)

Apart from the readability aspect of it, I am really interested in facts and figures. There are applications where the last mile of performance optimization squeezed do matter.

除了可读性方面,我对事实和数字很感兴趣。在应用程序中,最后一英里的性能优化被压缩了。

39 个解决方案

#1


272  

Patrick Smacchia blogged about this last month, with the following conclusions:

帕特里克•斯马基亚上月在博客中写道:

  • for loops on List are a bit more than 2 times cheaper than foreach loops on List.
  • 清单上的循环比列表上的每个循环要便宜2倍多。
  • Looping on array is around 2 times cheaper than looping on List.
  • 在数组中循环使用比在列表中循环要便宜2倍。
  • As a consequence, looping on array using for is 5 times cheaper than looping on List using foreach (which I believe, is what we all do).
  • 因此,使用for对数组进行循环要比使用foreach对列表进行循环便宜5倍(我相信我们都这么做)。

#2


150  

foreach loops demonstrate more specific intent than for loops.

foreach循环演示了比for循环更具体的意图。

Using a foreach loop demonstrates to anyone using your code that you are planning to do something to each member of a collection irrespective of its place in the collection. It also shows you aren't modifying the original collection (and throws an exception if you try to).

使用foreach循环演示给任何使用您的代码的人,您计划对集合中的每个成员做一些事情,而不考虑其在集合中的位置。它还显示您没有修改原始的集合(如果您尝试的话会抛出一个异常)。

The other advantage of foreach is that it works on any IEnumerable, where as for only makes sense for IList, where each element actually has an index.

foreach的另一个优点是它可以作用于任何IEnumerable,其中的as只对IList有意义,其中每个元素实际上都有一个索引。

However, if you need to use the index of an element, then of course you should be allowed to use a for loop. But if you don't need to use an index, having one is just cluttering your code.

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

There are no significant performance implications as far as I'm aware. At some stage in the future it might be easier to adapt code using foreach to run on multiple cores, but that's not something to worry about right now.

就我所知,这并不会对性能产生重大影响。在将来的某个阶段,使用foreach对代码进行调整以在多个核心上运行可能会更容易,但这不是现在需要担心的问题。

#3


137  

First, a counter-claim to Dmitry's answer. For arrays, the C# compiler emits largely the same code for foreach as it would for an equivalent for loop. That explains why for this benchmark, the results are basically the same:

首先,对德米特里的答案提出反诉。对于数组,c#编译器为foreach发出的代码与等效的For循环发出的代码基本相同。这就解释了为什么对于这个基准,结果基本上是一样的:

using System;
using System.Diagnostics;
using System.Linq;

class Test
{
    const int Size = 1000000;
    const int Iterations = 10000;

    static void Main()
    {
        double[] data = new double[Size];
        Random rng = new Random();
        for (int i=0; i < data.Length; i++)
        {
            data[i] = rng.NextDouble();
        }

        double correctSum = data.Sum();

        Stopwatch sw = Stopwatch.StartNew();
        for (int i=0; i < Iterations; i++)
        {
            double sum = 0;
            for (int j=0; j < data.Length; j++)
            {
                sum += data[j];
            }
            if (Math.Abs(sum-correctSum) > 0.1)
            {
                Console.WriteLine("Summation failed");
                return;
            }
        }
        sw.Stop();
        Console.WriteLine("For loop: {0}", sw.ElapsedMilliseconds);

        sw = Stopwatch.StartNew();
        for (int i=0; i < Iterations; i++)
        {
            double sum = 0;
            foreach (double d in data)
            {
                sum += d;
            }
            if (Math.Abs(sum-correctSum) > 0.1)
            {
                Console.WriteLine("Summation failed");
                return;
            }
        }
        sw.Stop();
        Console.WriteLine("Foreach loop: {0}", sw.ElapsedMilliseconds);
    }
}

Results:

结果:

For loop: 16638
Foreach loop: 16529

Next, validation that Greg's point about the collection type being important - change the array to a List<double> in the above, and you get radically different results. Not only is it significantly slower in general, but foreach becomes significantly slower than accessing by index. Having said that, I would still almost always prefer foreach to a for loop where it makes the code simpler - because readability is almost always important, whereas micro-optimisation rarely is.

接下来,验证Greg关于集合类型的观点是重要的——将数组更改为列表 ,您将得到完全不同的结果。它不仅总体上要慢得多,而且foreach要比按索引访问慢得多。说到这一点,我仍然几乎总是喜欢每个for循环,因为它使代码更简单——因为可读性几乎总是重要的,而微优化很少。

#4


48  

Any time there's arguments over performance, you just need to write a small test so that you can use quantitative results to support your case.

每当有关于性能的争论时,您只需编写一个小测试,以便您可以使用定量结果来支持您的案例。

Use the StopWatch class and repeat something a few million times, for accuracy. (This might be hard without a for loop):

使用秒表类,重复几百万次,以保证准确性。(如果没有for循环,这可能很难):

using System.Diagnostics;
//...
Stopwatch sw = new Stopwatch()
sw.Start()
for(int i = 0; i < 1000000;i ++)
{
    //do whatever it is you need to time
}
sw.Stop();
//print out sw.ElapsedMilliseconds

Fingers crossed the results of this show that the difference is negligible, and you might as well just do whatever results in the most maintainable code

手指交叉的结果表明,差异是可以忽略的,你也可以在最容易维护的代码中做任何结果。

#5


46  

It will always be close. For an array, sometimes for is slightly quicker, but foreach is more expressive, and offers LINQ, etc. In general, stick with foreach.

它会一直很近。对于一个数组,有时候For稍微快一点,但是foreach更有表现力,并且提供LINQ等等。一般来说,坚持foreach。

Additionally, foreach may be optimised in some scenarios. For example, a linked list might be terrible by indexer, but it might be quick by foreach. Actually, the standard LinkedList<T> doesn't even offer an indexer for this reason.

此外,foreach可能在某些场景中得到优化。例如,索引器链接列表可能很糟糕,但是foreach可能很快。实际上,标准的LinkedList 甚至没有为此提供索引器。

#6


32  

My guess is that it will probably not be significant in 99% of the cases, so why would you choose the faster instead of the most appropriate (as in easiest to understand/maintain)?

我的猜测是,99%的情况下,它可能并不重要,所以为什么选择更快的而不是最合适的(最容易理解/维护的)呢?

#7


30  

There is unlikely to be a huge performance difference between the two. As always, when faced with a "which is faster?" question, you should always think "I can measure this."

两者之间不太可能存在巨大的性能差异。像往常一样,当你面对一个“哪个更快?”的问题时,你应该想“我可以衡量这个”。

Write two loops that do the same thing in the body of the loop, execute and time them both, and see what the difference in speed is. Do this with both an almost-empty body, and a loop body similar to what you'll actually be doing. Also try it with the collection type that you're using, because different types of collections can have different performance characteristics.

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

#8


30  

There are very good reasons to prefer foreach loops over for loops. If you can use a foreach loop, your boss is right that you should.

有很好的理由选择foreach循环而不是for循环。如果你能使用foreach循环,你的老板认为你应该这么做。

However, not every iteration is simply going through a list in order one by one. If he is forbidding for, yes that is wrong.

然而,并不是每个迭代都只是按顺序逐个地遍历一个列表。如果他禁止,那是不对的。

If I were you, what I would do is turn all of your natural for loops into recursion. That'd teach him, and it's also a good mental exercise for you.

如果我是你,我要做的就是把所有的自然循环变成递归。这可以教会他,对你来说也是一种很好的心理训练。

#9


12  

Jeffrey Richter on TechEd 2005:

杰弗里·里希特在TechEd上说:

"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..."

“多年来,我逐渐认识到c#编译器对我来说基本上就是个骗子。”. .“它存在于很多方面。”. .“就像你做一个foreach循环……”. .“…这是您编写的一小行代码,但是c#编译器为了实现这一点而输出的代码是惊人的。它把一个try / finally块,在finally块IDisposable接口投你的变量,如果演员成功调用Dispose方法,内部循环调用当前财产和MoveNext方法反复循环内,封面下面创建对象。很多人用foreach因为它很容易编码,很容易做. .“foreach在性能上不是很好,如果你用方括号符号来迭代集合,只做索引,那就快多了,而且它不会在堆上创建任何对象……”

On-Demand Webcast: http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032292286&EventCategory=3&culture=en-US&CountryCode=US

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

#10


11  

This is ridiculous. There's no compelling reason to ban the for-loop, performance-wise or other.

这是荒谬的。没有令人信服的理由来禁止for循环,性能上或其他方面。

See Jon Skeet's blog for a performance benchmark and other arguments.

有关性能基准和其他参数,请参阅Jon Skeet的博客。

#11


11  

In cases where you work with a collection of objects, foreach is better, but if you increment a number, a for loop is better.

在您使用对象集合的情况下,foreach比较好,但是如果您增加一个数字,那么for循环就更好了。

Note that in the last case, you could do something like:

注意,在最后一种情况下,您可以做以下事情:

foreach (int i in Enumerable.Range(1, 10))...

But it certainly doesn't perform better, it actually has worse performance compared to a for.

但它的表现肯定不是更好,它实际上比a更差。

#12


9  

This should save you:

这应该为您节省:

public IEnumerator<int> For(int start, int end, int step) {
    int n = start;
    while (n <= end) {
        yield n;
        n += step;
    }
}

Use:

使用:

foreach (int n in For(1, 200, 4)) {
    Console.WriteLine(n);
}

For greater win, you may take three delegates as parameters.

为了获得更大的胜利,您可以将三个委托作为参数。

#13


7  

The differences in speed in a for- and a foreach-loop are tiny when you're looping through common structures like arrays, lists, etc, and doing a LINQ query over the collection is almost always slightly slower, although it's nicer to write! As the other posters said, go for expressiveness rather than a millisecond of extra performance.

当您循环遍历诸如数组、列表等公共结构时,for-和foreacher循环的速度差异是很小的,并且在集合上执行LINQ查询几乎总是稍微慢一点,尽管这样更好写!正如其他的海报所言,要有表现力,而不是一毫秒的额外表演。

What hasn't been said so far is that when a foreach loop is compiled, it is optimised by the compiler based on the collection it is iterating over. That means that when you're not sure which loop to use, you should use the foreach loop - it will generate the best loop for you when it gets compiled. It's more readable too.

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

Another key advantage with the foreach loop is that if your collection implementation changes (from an int array to a List<int> for example) then your foreach loop won't require any code changes:

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

foreach (int i in myCollection)

The above is the same no matter what type your collection is, whereas in your for loop, the following will not build if you changed myCollection from an array to a List:

以上是相同的,不管你的集合是什么类型,而在你的for循环中,如果你将myCollection从数组改为列表,下面的内容将不会构建:

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

#14


7  

"Are there any arguments I could use to help me convince him the for loop is acceptable to use?"

“有什么论据可以帮助我说服他使用for循环是可以接受的吗?”

No, if your boss is micromanaging to the level of telling you what programming language constructs to use, there's really nothing you can say. Sorry.

不,如果你的老板正在对你进行微观管理,告诉你应该使用什么编程语言结构,你真的说不出什么。对不起。

#15


7  

It probably depends on the type of collection you are enumerating and the implementation of its indexer. In general though, using foreach is likely to be a better approach.

它可能取决于正在枚举的集合的类型和它的索引器的实现。一般来说,使用foreach可能是更好的方法。

Also, it'll work with any IEnumerable - not just things with indexers.

而且,它可以使用任何IEnumerable——不仅仅是索引器。

#16


6  

Every language construct has an appropriate time and place for usage. There is a reason the C# language has a four separate iteration statements - each is there for a specific purpose, and has an appropriate use.

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

I recommend sitting down with your boss and trying to rationally explain why a for loop has a purpose. There are times when a for iteration block more clearly describes an algorithm than a foreach iteration. When this is true, it is appropriate to use them.

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

I'd also point out to your boss - Performance is not, and should not be an issue in any practical way - it's more a matter of expression the algorithm in a succinct, meaningful, maintainable manner. Micro-optimizations like this miss the point of performance optimization completely, since any real performance benefit will come from algorithmic redesign and refactoring, not loop restructuring.

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

If, after a rational discussion, there is still this authoritarian view, it is up to you as to how to proceed. Personally, I would not be happy working in an environment where rational thought is discouraged, and would consider moving to another position under a different employer. However, I strongly recommend discussion prior to getting upset - there may just be a simple misunderstanding in place.

如果经过理性的讨论,仍然存在这种专制的观点,那么如何继续下去就取决于你了。就我个人而言,我不愿意在这样一个环境中工作,在这种环境下,理性的想法是不被鼓励的,并且会考虑换到另一个雇主的另一个职位。然而,我强烈建议在心烦意乱之前进行讨论——可能存在一个简单的误解。

#17


6  

This has the same two answers as most "which is faster" questions:

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

1) If you don't measure, you don't know.

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

2) (Because...) It depends.

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

It depends on how expensive the "MoveNext()" method is, relative to how expensive the "this[int index]" method is, for the type (or types) of IEnumerable that you will be iterating over.

它取决于“MoveNext()”方法的开销,相对于“这个(int index)”方法的代价是多少,对于您将要迭代的IEnumerable类型(或类型)来说是如此。

The "foreach" keyword is shorthand for a series of operations - it calls GetEnumerator() once on the IEnumerable, it calls MoveNext() once per iteration, it does some type checking, and so on. The thing most likely to impact performance measurements is the cost of MoveNext() since that gets invoked O(N) times. Maybe it's cheap, but maybe it's not.

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

The "for" keyword looks more predictable, but inside most "for" loops you'll find something like "collection[index]". This looks like a simple array indexing operation, but it's actually a method call, whose cost depends entirely on the nature of the collection that you're iterating over. Probably it's cheap, but maybe it's not.

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

If the collection's underlying structure is essentially a linked list, MoveNext is dirt-cheap, but the indexer might have O(N) cost, making the true cost of a "for" loop O(N*N).

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

#18


5  

It is what you do inside the loop that affects perfomance, not the actual looping construct (assuming your case is non-trivial).

影响性能的是循环内的操作,而不是实际的循环构造(假设您的情况是非平凡的)。

#19


5  

Whether for is faster than foreach is really besides the point. I seriously doubt that choosing one over the other will make a significant impact on your performance.

for是否比foreach真的无关紧要。我非常怀疑,选择其中之一会对你的表现产生重大影响。

The best way to optimize your application is through profiling of the actual code. That will pinpoint the methods that account for the most work/time. Optimize those first. If performance is still not acceptable, repeat the procedure.

优化应用程序的最佳方法是对实际代码进行分析。这将精确地指出哪些方法占了最多的工作/时间。这些第一次优化。如果仍然不能接受性能,请重复此过程。

As a general rule I would recommend to stay away from micro optimizations as they will rarely yield any significant gains. Only exception is when optimizing identified hot paths (i.e. if your profiling identifies a few highly used methods, it may make sense to optimize these extensively).

一般来说,我建议远离微优化,因为微优化很少会带来任何显著的收益。唯一的例外是在优化已识别的热路径时(例如,如果您的分析识别了一些高度使用的方法,那么对这些方法进行广泛的优化可能是有意义的)。

#20


4  

The two will run almost exactly the same way. Write some code to use both, then show him the IL. It should show comparable computations, meaning no difference in performance.

两者的运行方式几乎完全相同。编写一些代码来使用这两种方法,然后向他显示IL。

#21


4  

I found the foreach loop which iterating through a List faster. See my test results below. In the code below I iterate an array of size 100, 10000 and 100000 separately using for and foreach loop to measure the time.

我找到了foreach循环,它可以更快地遍历列表。请看我的测试结果。在下面的代码中,我分别使用for和foreach循环迭代大小为100、10000和100000的数组来度量时间。

在。net中,哪个循环运行得更快,“for”还是“foreach”?

private static void MeasureTime()
    {
        var array = new int[10000];
        var list = array.ToList();
        Console.WriteLine("Array size: {0}", array.Length);

        Console.WriteLine("Array For loop ......");
        var stopWatch = Stopwatch.StartNew();
        for (int i = 0; i < array.Length; i++)
        {
            Thread.Sleep(1);
        }
        stopWatch.Stop();
        Console.WriteLine("Time take to run the for loop is {0} millisecond", stopWatch.ElapsedMilliseconds);

        Console.WriteLine(" ");
        Console.WriteLine("Array Foreach loop ......");
        var stopWatch1 = Stopwatch.StartNew();
        foreach (var item in array)
        {
            Thread.Sleep(1);
        }
        stopWatch1.Stop();
        Console.WriteLine("Time take to run the foreach loop is {0} millisecond", stopWatch1.ElapsedMilliseconds);

        Console.WriteLine(" ");
        Console.WriteLine("List For loop ......");
        var stopWatch2 = Stopwatch.StartNew();
        for (int i = 0; i < list.Count; i++)
        {
            Thread.Sleep(1);
        }
        stopWatch2.Stop();
        Console.WriteLine("Time take to run the for loop is {0} millisecond", stopWatch2.ElapsedMilliseconds);

        Console.WriteLine(" ");
        Console.WriteLine("List Foreach loop ......");
        var stopWatch3 = Stopwatch.StartNew();
        foreach (var item in list)
        {
            Thread.Sleep(1);
        }
        stopWatch3.Stop();
        Console.WriteLine("Time take to run the foreach loop is {0} millisecond", stopWatch3.ElapsedMilliseconds);
    }

UPDATED

After @jgauffin suggestion I used @johnskeet code and found that the for loop with array is faster than following,

在@jgauffin的建议之后,我使用了@johnskeet代码,发现数组的for循环比下面的要快,

  • Foreach loop with array.
  • Foreach循环数组。
  • For loop with list.
  • For循环和列表。
  • Foreach loop with list.
  • Foreach循环列表。

See my test results and code below,

请看下面我的测试结果和代码,

在。net中,哪个循环运行得更快,“for”还是“foreach”?

private static void MeasureNewTime()
    {
        var data = new double[Size];
        var rng = new Random();
        for (int i = 0; i < data.Length; i++)
        {
            data[i] = rng.NextDouble();
        }
        Console.WriteLine("Lenght of array: {0}", data.Length);
        Console.WriteLine("No. of iteration: {0}", Iterations);
        Console.WriteLine(" ");
        double correctSum = data.Sum();

        Stopwatch sw = Stopwatch.StartNew();
        for (int i = 0; i < Iterations; i++)
        {
            double sum = 0;
            for (int j = 0; j < data.Length; j++)
            {
                sum += data[j];
            }
            if (Math.Abs(sum - correctSum) > 0.1)
            {
                Console.WriteLine("Summation failed");
                return;
            }
        }
        sw.Stop();
        Console.WriteLine("For loop with Array: {0}", sw.ElapsedMilliseconds);

        sw = Stopwatch.StartNew();
        for (var i = 0; i < Iterations; i++)
        {
            double sum = 0;
            foreach (double d in data)
            {
                sum += d;
            }
            if (Math.Abs(sum - correctSum) > 0.1)
            {
                Console.WriteLine("Summation failed");
                return;
            }
        }
        sw.Stop();
        Console.WriteLine("Foreach loop with Array: {0}", sw.ElapsedMilliseconds);
        Console.WriteLine(" ");

        var dataList = data.ToList();
        sw = Stopwatch.StartNew();
        for (int i = 0; i < Iterations; i++)
        {
            double sum = 0;
            for (int j = 0; j < dataList.Count; j++)
            {
                sum += data[j];
            }
            if (Math.Abs(sum - correctSum) > 0.1)
            {
                Console.WriteLine("Summation failed");
                return;
            }
        }
        sw.Stop();
        Console.WriteLine("For loop with List: {0}", sw.ElapsedMilliseconds);

        sw = Stopwatch.StartNew();
        for (int i = 0; i < Iterations; i++)
        {
            double sum = 0;
            foreach (double d in dataList)
            {
                sum += d;
            }
            if (Math.Abs(sum - correctSum) > 0.1)
            {
                Console.WriteLine("Summation failed");
                return;
            }
        }
        sw.Stop();
        Console.WriteLine("Foreach loop with List: {0}", sw.ElapsedMilliseconds);
    }

#22


3  

for has more simple logic to implement so it's faster than foreach.

for有更简单的逻辑来实现,所以它比foreach要快。

#23


3  

Unless you're in a specific speed optimization process, I would say use whichever method produces the easiest to read and maintain code.

除非您处于特定的速度优化过程中,否则我建议使用任何最容易读取和维护代码的方法。

If an iterator is already setup, like with one of the collection classes, then the foreach is a good easy option. And if it's an integer range you're iterating, then for is probably cleaner.

如果一个迭代器已经设置好了,比如有一个集合类,那么foreach是一个很好的选择。如果它是一个整数范围,那么for可能更简洁。

#24


3  

Jeffrey Richter talked the performance difference between for and foreach on a recent podcast: http://pixel8.infragistics.com/shows/everything.aspx#Episode:9317

Jeffrey Richter在最近的播客上谈到了for和foreach之间的性能差异:http://pixel8.infragistics.com/shows/everything.aspx#每集:9317

#25


3  

In most cases there's really no difference.

在大多数情况下没有什么区别。

Typically you always have to use foreach when you don't have an explicit numerical index, and you always have to use for when you don't actually have an iterable collection (e.g. iterating over a two-dimensional array grid in an upper triangle). There are some cases where you have a choice.

通常,当您没有一个显式的数字索引时,您总是必须使用foreach,而且当您实际上没有可迭代的集合时,您总是需要使用它(例如,在一个上三角形中迭代一个二维数组网格)。有些情况下你可以选择。

One could argue that for loops can be a little more difficult to maintain if magic numbers start to appear in the code. You should be right to be annoyed at not being able to use a for loop and have to build a collection or use a lambda to build a subcollection instead just because for loops have been banned.

有人可能会说,如果代码中出现了不可思议的数字,那么for循环维护起来会有点困难。您应该对不能使用for循环感到愤怒,并且必须构建一个集合或者使用lambda来构建一个子集合,而不是因为for循环被禁止。

#26


3  

Really screw with his head and go for an IQueryable .foreach closure instead:

真的用他的头去拧一拧,然后去找一个易趣的。

myList.ForEach(c => Console.WriteLine(c.ToString());

myList。ForEach(c = > Console.WriteLine(c.ToString());

LOL

哈哈

#27


2  

I wouldn't expect anyone to find a "huge" performance difference between the two.

我不认为会有人发现两者之间存在“巨大”的性能差异。

I guess the answer depends on the whether the collection you are trying to access has a faster indexer access implementation or a faster IEnumerator access implementation. Since IEnumerator often uses the indexer and just holds a copy of the current index position, I would expect enumerator access to be at least as slow or slower than direct index access, but not by much.

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

Of course this answer doesn't account for any optimizations the compiler may implement.

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

#28


2  

Keep in mind that the for-loop and foreach-loop are not always equivalent. List enumerators will throw an exception if the list changes, but you won't always get that warning with a normal for loop. You might even get a different exception if the list changes at just the wrong time.

记住,for循环和foreachloop并不总是等价的。如果列表发生变化,列表枚举器将抛出一个异常,但是您不会总是使用正常的for循环获得该警告。如果列表在错误的时间发生变化,您甚至可能得到不同的异常。

#29


2  

It seems a bit strange to totally forbid the use of something like a for loop.

完全禁止使用for循环之类的东西似乎有点奇怪。

There's an interesting article here that covers a lot of the performance differences between the two loops.

这里有一篇有趣的文章,它涵盖了两个循环之间的许多性能差异。

I would say personally I find foreach a bit more readable over for loops but you should use the best for the job at hand and not have to write extra long code to include a foreach loop if a for loop is more appropriate.

我个人认为,对于for循环,我发现每一个都更容易读,但是您应该尽可能地使用手边的工作,而不必编写额外的长代码来包含foreach循环,如果for循环更合适的话。

#30


1  

I did test it a while ago, with the result that a for loop is much faster than a foreach loop. The cause is simple, the foreach loop first needs to instantiate an IEnumerator for the collection.

我不久前确实对它进行了测试,结果是for循环要比foreach循环快得多。原因很简单,foreach循环首先需要实例化集合的IEnumerator。

#1


272  

Patrick Smacchia blogged about this last month, with the following conclusions:

帕特里克•斯马基亚上月在博客中写道:

  • for loops on List are a bit more than 2 times cheaper than foreach loops on List.
  • 清单上的循环比列表上的每个循环要便宜2倍多。
  • Looping on array is around 2 times cheaper than looping on List.
  • 在数组中循环使用比在列表中循环要便宜2倍。
  • As a consequence, looping on array using for is 5 times cheaper than looping on List using foreach (which I believe, is what we all do).
  • 因此,使用for对数组进行循环要比使用foreach对列表进行循环便宜5倍(我相信我们都这么做)。

#2


150  

foreach loops demonstrate more specific intent than for loops.

foreach循环演示了比for循环更具体的意图。

Using a foreach loop demonstrates to anyone using your code that you are planning to do something to each member of a collection irrespective of its place in the collection. It also shows you aren't modifying the original collection (and throws an exception if you try to).

使用foreach循环演示给任何使用您的代码的人,您计划对集合中的每个成员做一些事情,而不考虑其在集合中的位置。它还显示您没有修改原始的集合(如果您尝试的话会抛出一个异常)。

The other advantage of foreach is that it works on any IEnumerable, where as for only makes sense for IList, where each element actually has an index.

foreach的另一个优点是它可以作用于任何IEnumerable,其中的as只对IList有意义,其中每个元素实际上都有一个索引。

However, if you need to use the index of an element, then of course you should be allowed to use a for loop. But if you don't need to use an index, having one is just cluttering your code.

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

There are no significant performance implications as far as I'm aware. At some stage in the future it might be easier to adapt code using foreach to run on multiple cores, but that's not something to worry about right now.

就我所知,这并不会对性能产生重大影响。在将来的某个阶段,使用foreach对代码进行调整以在多个核心上运行可能会更容易,但这不是现在需要担心的问题。

#3


137  

First, a counter-claim to Dmitry's answer. For arrays, the C# compiler emits largely the same code for foreach as it would for an equivalent for loop. That explains why for this benchmark, the results are basically the same:

首先,对德米特里的答案提出反诉。对于数组,c#编译器为foreach发出的代码与等效的For循环发出的代码基本相同。这就解释了为什么对于这个基准,结果基本上是一样的:

using System;
using System.Diagnostics;
using System.Linq;

class Test
{
    const int Size = 1000000;
    const int Iterations = 10000;

    static void Main()
    {
        double[] data = new double[Size];
        Random rng = new Random();
        for (int i=0; i < data.Length; i++)
        {
            data[i] = rng.NextDouble();
        }

        double correctSum = data.Sum();

        Stopwatch sw = Stopwatch.StartNew();
        for (int i=0; i < Iterations; i++)
        {
            double sum = 0;
            for (int j=0; j < data.Length; j++)
            {
                sum += data[j];
            }
            if (Math.Abs(sum-correctSum) > 0.1)
            {
                Console.WriteLine("Summation failed");
                return;
            }
        }
        sw.Stop();
        Console.WriteLine("For loop: {0}", sw.ElapsedMilliseconds);

        sw = Stopwatch.StartNew();
        for (int i=0; i < Iterations; i++)
        {
            double sum = 0;
            foreach (double d in data)
            {
                sum += d;
            }
            if (Math.Abs(sum-correctSum) > 0.1)
            {
                Console.WriteLine("Summation failed");
                return;
            }
        }
        sw.Stop();
        Console.WriteLine("Foreach loop: {0}", sw.ElapsedMilliseconds);
    }
}

Results:

结果:

For loop: 16638
Foreach loop: 16529

Next, validation that Greg's point about the collection type being important - change the array to a List<double> in the above, and you get radically different results. Not only is it significantly slower in general, but foreach becomes significantly slower than accessing by index. Having said that, I would still almost always prefer foreach to a for loop where it makes the code simpler - because readability is almost always important, whereas micro-optimisation rarely is.

接下来,验证Greg关于集合类型的观点是重要的——将数组更改为列表 ,您将得到完全不同的结果。它不仅总体上要慢得多,而且foreach要比按索引访问慢得多。说到这一点,我仍然几乎总是喜欢每个for循环,因为它使代码更简单——因为可读性几乎总是重要的,而微优化很少。

#4


48  

Any time there's arguments over performance, you just need to write a small test so that you can use quantitative results to support your case.

每当有关于性能的争论时,您只需编写一个小测试,以便您可以使用定量结果来支持您的案例。

Use the StopWatch class and repeat something a few million times, for accuracy. (This might be hard without a for loop):

使用秒表类,重复几百万次,以保证准确性。(如果没有for循环,这可能很难):

using System.Diagnostics;
//...
Stopwatch sw = new Stopwatch()
sw.Start()
for(int i = 0; i < 1000000;i ++)
{
    //do whatever it is you need to time
}
sw.Stop();
//print out sw.ElapsedMilliseconds

Fingers crossed the results of this show that the difference is negligible, and you might as well just do whatever results in the most maintainable code

手指交叉的结果表明,差异是可以忽略的,你也可以在最容易维护的代码中做任何结果。

#5


46  

It will always be close. For an array, sometimes for is slightly quicker, but foreach is more expressive, and offers LINQ, etc. In general, stick with foreach.

它会一直很近。对于一个数组,有时候For稍微快一点,但是foreach更有表现力,并且提供LINQ等等。一般来说,坚持foreach。

Additionally, foreach may be optimised in some scenarios. For example, a linked list might be terrible by indexer, but it might be quick by foreach. Actually, the standard LinkedList<T> doesn't even offer an indexer for this reason.

此外,foreach可能在某些场景中得到优化。例如,索引器链接列表可能很糟糕,但是foreach可能很快。实际上,标准的LinkedList 甚至没有为此提供索引器。

#6


32  

My guess is that it will probably not be significant in 99% of the cases, so why would you choose the faster instead of the most appropriate (as in easiest to understand/maintain)?

我的猜测是,99%的情况下,它可能并不重要,所以为什么选择更快的而不是最合适的(最容易理解/维护的)呢?

#7


30  

There is unlikely to be a huge performance difference between the two. As always, when faced with a "which is faster?" question, you should always think "I can measure this."

两者之间不太可能存在巨大的性能差异。像往常一样,当你面对一个“哪个更快?”的问题时,你应该想“我可以衡量这个”。

Write two loops that do the same thing in the body of the loop, execute and time them both, and see what the difference in speed is. Do this with both an almost-empty body, and a loop body similar to what you'll actually be doing. Also try it with the collection type that you're using, because different types of collections can have different performance characteristics.

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

#8


30  

There are very good reasons to prefer foreach loops over for loops. If you can use a foreach loop, your boss is right that you should.

有很好的理由选择foreach循环而不是for循环。如果你能使用foreach循环,你的老板认为你应该这么做。

However, not every iteration is simply going through a list in order one by one. If he is forbidding for, yes that is wrong.

然而,并不是每个迭代都只是按顺序逐个地遍历一个列表。如果他禁止,那是不对的。

If I were you, what I would do is turn all of your natural for loops into recursion. That'd teach him, and it's also a good mental exercise for you.

如果我是你,我要做的就是把所有的自然循环变成递归。这可以教会他,对你来说也是一种很好的心理训练。

#9


12  

Jeffrey Richter on TechEd 2005:

杰弗里·里希特在TechEd上说:

"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..."

“多年来,我逐渐认识到c#编译器对我来说基本上就是个骗子。”. .“它存在于很多方面。”. .“就像你做一个foreach循环……”. .“…这是您编写的一小行代码,但是c#编译器为了实现这一点而输出的代码是惊人的。它把一个try / finally块,在finally块IDisposable接口投你的变量,如果演员成功调用Dispose方法,内部循环调用当前财产和MoveNext方法反复循环内,封面下面创建对象。很多人用foreach因为它很容易编码,很容易做. .“foreach在性能上不是很好,如果你用方括号符号来迭代集合,只做索引,那就快多了,而且它不会在堆上创建任何对象……”

On-Demand Webcast: http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032292286&EventCategory=3&culture=en-US&CountryCode=US

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

#10


11  

This is ridiculous. There's no compelling reason to ban the for-loop, performance-wise or other.

这是荒谬的。没有令人信服的理由来禁止for循环,性能上或其他方面。

See Jon Skeet's blog for a performance benchmark and other arguments.

有关性能基准和其他参数,请参阅Jon Skeet的博客。

#11


11  

In cases where you work with a collection of objects, foreach is better, but if you increment a number, a for loop is better.

在您使用对象集合的情况下,foreach比较好,但是如果您增加一个数字,那么for循环就更好了。

Note that in the last case, you could do something like:

注意,在最后一种情况下,您可以做以下事情:

foreach (int i in Enumerable.Range(1, 10))...

But it certainly doesn't perform better, it actually has worse performance compared to a for.

但它的表现肯定不是更好,它实际上比a更差。

#12


9  

This should save you:

这应该为您节省:

public IEnumerator<int> For(int start, int end, int step) {
    int n = start;
    while (n <= end) {
        yield n;
        n += step;
    }
}

Use:

使用:

foreach (int n in For(1, 200, 4)) {
    Console.WriteLine(n);
}

For greater win, you may take three delegates as parameters.

为了获得更大的胜利,您可以将三个委托作为参数。

#13


7  

The differences in speed in a for- and a foreach-loop are tiny when you're looping through common structures like arrays, lists, etc, and doing a LINQ query over the collection is almost always slightly slower, although it's nicer to write! As the other posters said, go for expressiveness rather than a millisecond of extra performance.

当您循环遍历诸如数组、列表等公共结构时,for-和foreacher循环的速度差异是很小的,并且在集合上执行LINQ查询几乎总是稍微慢一点,尽管这样更好写!正如其他的海报所言,要有表现力,而不是一毫秒的额外表演。

What hasn't been said so far is that when a foreach loop is compiled, it is optimised by the compiler based on the collection it is iterating over. That means that when you're not sure which loop to use, you should use the foreach loop - it will generate the best loop for you when it gets compiled. It's more readable too.

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

Another key advantage with the foreach loop is that if your collection implementation changes (from an int array to a List<int> for example) then your foreach loop won't require any code changes:

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

foreach (int i in myCollection)

The above is the same no matter what type your collection is, whereas in your for loop, the following will not build if you changed myCollection from an array to a List:

以上是相同的,不管你的集合是什么类型,而在你的for循环中,如果你将myCollection从数组改为列表,下面的内容将不会构建:

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

#14


7  

"Are there any arguments I could use to help me convince him the for loop is acceptable to use?"

“有什么论据可以帮助我说服他使用for循环是可以接受的吗?”

No, if your boss is micromanaging to the level of telling you what programming language constructs to use, there's really nothing you can say. Sorry.

不,如果你的老板正在对你进行微观管理,告诉你应该使用什么编程语言结构,你真的说不出什么。对不起。

#15


7  

It probably depends on the type of collection you are enumerating and the implementation of its indexer. In general though, using foreach is likely to be a better approach.

它可能取决于正在枚举的集合的类型和它的索引器的实现。一般来说,使用foreach可能是更好的方法。

Also, it'll work with any IEnumerable - not just things with indexers.

而且,它可以使用任何IEnumerable——不仅仅是索引器。

#16


6  

Every language construct has an appropriate time and place for usage. There is a reason the C# language has a four separate iteration statements - each is there for a specific purpose, and has an appropriate use.

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

I recommend sitting down with your boss and trying to rationally explain why a for loop has a purpose. There are times when a for iteration block more clearly describes an algorithm than a foreach iteration. When this is true, it is appropriate to use them.

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

I'd also point out to your boss - Performance is not, and should not be an issue in any practical way - it's more a matter of expression the algorithm in a succinct, meaningful, maintainable manner. Micro-optimizations like this miss the point of performance optimization completely, since any real performance benefit will come from algorithmic redesign and refactoring, not loop restructuring.

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

If, after a rational discussion, there is still this authoritarian view, it is up to you as to how to proceed. Personally, I would not be happy working in an environment where rational thought is discouraged, and would consider moving to another position under a different employer. However, I strongly recommend discussion prior to getting upset - there may just be a simple misunderstanding in place.

如果经过理性的讨论,仍然存在这种专制的观点,那么如何继续下去就取决于你了。就我个人而言,我不愿意在这样一个环境中工作,在这种环境下,理性的想法是不被鼓励的,并且会考虑换到另一个雇主的另一个职位。然而,我强烈建议在心烦意乱之前进行讨论——可能存在一个简单的误解。

#17


6  

This has the same two answers as most "which is faster" questions:

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

1) If you don't measure, you don't know.

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

2) (Because...) It depends.

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

It depends on how expensive the "MoveNext()" method is, relative to how expensive the "this[int index]" method is, for the type (or types) of IEnumerable that you will be iterating over.

它取决于“MoveNext()”方法的开销,相对于“这个(int index)”方法的代价是多少,对于您将要迭代的IEnumerable类型(或类型)来说是如此。

The "foreach" keyword is shorthand for a series of operations - it calls GetEnumerator() once on the IEnumerable, it calls MoveNext() once per iteration, it does some type checking, and so on. The thing most likely to impact performance measurements is the cost of MoveNext() since that gets invoked O(N) times. Maybe it's cheap, but maybe it's not.

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

The "for" keyword looks more predictable, but inside most "for" loops you'll find something like "collection[index]". This looks like a simple array indexing operation, but it's actually a method call, whose cost depends entirely on the nature of the collection that you're iterating over. Probably it's cheap, but maybe it's not.

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

If the collection's underlying structure is essentially a linked list, MoveNext is dirt-cheap, but the indexer might have O(N) cost, making the true cost of a "for" loop O(N*N).

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

#18


5  

It is what you do inside the loop that affects perfomance, not the actual looping construct (assuming your case is non-trivial).

影响性能的是循环内的操作,而不是实际的循环构造(假设您的情况是非平凡的)。

#19


5  

Whether for is faster than foreach is really besides the point. I seriously doubt that choosing one over the other will make a significant impact on your performance.

for是否比foreach真的无关紧要。我非常怀疑,选择其中之一会对你的表现产生重大影响。

The best way to optimize your application is through profiling of the actual code. That will pinpoint the methods that account for the most work/time. Optimize those first. If performance is still not acceptable, repeat the procedure.

优化应用程序的最佳方法是对实际代码进行分析。这将精确地指出哪些方法占了最多的工作/时间。这些第一次优化。如果仍然不能接受性能,请重复此过程。

As a general rule I would recommend to stay away from micro optimizations as they will rarely yield any significant gains. Only exception is when optimizing identified hot paths (i.e. if your profiling identifies a few highly used methods, it may make sense to optimize these extensively).

一般来说,我建议远离微优化,因为微优化很少会带来任何显著的收益。唯一的例外是在优化已识别的热路径时(例如,如果您的分析识别了一些高度使用的方法,那么对这些方法进行广泛的优化可能是有意义的)。

#20


4  

The two will run almost exactly the same way. Write some code to use both, then show him the IL. It should show comparable computations, meaning no difference in performance.

两者的运行方式几乎完全相同。编写一些代码来使用这两种方法,然后向他显示IL。

#21


4  

I found the foreach loop which iterating through a List faster. See my test results below. In the code below I iterate an array of size 100, 10000 and 100000 separately using for and foreach loop to measure the time.

我找到了foreach循环,它可以更快地遍历列表。请看我的测试结果。在下面的代码中,我分别使用for和foreach循环迭代大小为100、10000和100000的数组来度量时间。

在。net中,哪个循环运行得更快,“for”还是“foreach”?

private static void MeasureTime()
    {
        var array = new int[10000];
        var list = array.ToList();
        Console.WriteLine("Array size: {0}", array.Length);

        Console.WriteLine("Array For loop ......");
        var stopWatch = Stopwatch.StartNew();
        for (int i = 0; i < array.Length; i++)
        {
            Thread.Sleep(1);
        }
        stopWatch.Stop();
        Console.WriteLine("Time take to run the for loop is {0} millisecond", stopWatch.ElapsedMilliseconds);

        Console.WriteLine(" ");
        Console.WriteLine("Array Foreach loop ......");
        var stopWatch1 = Stopwatch.StartNew();
        foreach (var item in array)
        {
            Thread.Sleep(1);
        }
        stopWatch1.Stop();
        Console.WriteLine("Time take to run the foreach loop is {0} millisecond", stopWatch1.ElapsedMilliseconds);

        Console.WriteLine(" ");
        Console.WriteLine("List For loop ......");
        var stopWatch2 = Stopwatch.StartNew();
        for (int i = 0; i < list.Count; i++)
        {
            Thread.Sleep(1);
        }
        stopWatch2.Stop();
        Console.WriteLine("Time take to run the for loop is {0} millisecond", stopWatch2.ElapsedMilliseconds);

        Console.WriteLine(" ");
        Console.WriteLine("List Foreach loop ......");
        var stopWatch3 = Stopwatch.StartNew();
        foreach (var item in list)
        {
            Thread.Sleep(1);
        }
        stopWatch3.Stop();
        Console.WriteLine("Time take to run the foreach loop is {0} millisecond", stopWatch3.ElapsedMilliseconds);
    }

UPDATED

After @jgauffin suggestion I used @johnskeet code and found that the for loop with array is faster than following,

在@jgauffin的建议之后,我使用了@johnskeet代码,发现数组的for循环比下面的要快,

  • Foreach loop with array.
  • Foreach循环数组。
  • For loop with list.
  • For循环和列表。
  • Foreach loop with list.
  • Foreach循环列表。

See my test results and code below,

请看下面我的测试结果和代码,

在。net中,哪个循环运行得更快,“for”还是“foreach”?

private static void MeasureNewTime()
    {
        var data = new double[Size];
        var rng = new Random();
        for (int i = 0; i < data.Length; i++)
        {
            data[i] = rng.NextDouble();
        }
        Console.WriteLine("Lenght of array: {0}", data.Length);
        Console.WriteLine("No. of iteration: {0}", Iterations);
        Console.WriteLine(" ");
        double correctSum = data.Sum();

        Stopwatch sw = Stopwatch.StartNew();
        for (int i = 0; i < Iterations; i++)
        {
            double sum = 0;
            for (int j = 0; j < data.Length; j++)
            {
                sum += data[j];
            }
            if (Math.Abs(sum - correctSum) > 0.1)
            {
                Console.WriteLine("Summation failed");
                return;
            }
        }
        sw.Stop();
        Console.WriteLine("For loop with Array: {0}", sw.ElapsedMilliseconds);

        sw = Stopwatch.StartNew();
        for (var i = 0; i < Iterations; i++)
        {
            double sum = 0;
            foreach (double d in data)
            {
                sum += d;
            }
            if (Math.Abs(sum - correctSum) > 0.1)
            {
                Console.WriteLine("Summation failed");
                return;
            }
        }
        sw.Stop();
        Console.WriteLine("Foreach loop with Array: {0}", sw.ElapsedMilliseconds);
        Console.WriteLine(" ");

        var dataList = data.ToList();
        sw = Stopwatch.StartNew();
        for (int i = 0; i < Iterations; i++)
        {
            double sum = 0;
            for (int j = 0; j < dataList.Count; j++)
            {
                sum += data[j];
            }
            if (Math.Abs(sum - correctSum) > 0.1)
            {
                Console.WriteLine("Summation failed");
                return;
            }
        }
        sw.Stop();
        Console.WriteLine("For loop with List: {0}", sw.ElapsedMilliseconds);

        sw = Stopwatch.StartNew();
        for (int i = 0; i < Iterations; i++)
        {
            double sum = 0;
            foreach (double d in dataList)
            {
                sum += d;
            }
            if (Math.Abs(sum - correctSum) > 0.1)
            {
                Console.WriteLine("Summation failed");
                return;
            }
        }
        sw.Stop();
        Console.WriteLine("Foreach loop with List: {0}", sw.ElapsedMilliseconds);
    }

#22


3  

for has more simple logic to implement so it's faster than foreach.

for有更简单的逻辑来实现,所以它比foreach要快。

#23


3  

Unless you're in a specific speed optimization process, I would say use whichever method produces the easiest to read and maintain code.

除非您处于特定的速度优化过程中,否则我建议使用任何最容易读取和维护代码的方法。

If an iterator is already setup, like with one of the collection classes, then the foreach is a good easy option. And if it's an integer range you're iterating, then for is probably cleaner.

如果一个迭代器已经设置好了,比如有一个集合类,那么foreach是一个很好的选择。如果它是一个整数范围,那么for可能更简洁。

#24


3  

Jeffrey Richter talked the performance difference between for and foreach on a recent podcast: http://pixel8.infragistics.com/shows/everything.aspx#Episode:9317

Jeffrey Richter在最近的播客上谈到了for和foreach之间的性能差异:http://pixel8.infragistics.com/shows/everything.aspx#每集:9317

#25


3  

In most cases there's really no difference.

在大多数情况下没有什么区别。

Typically you always have to use foreach when you don't have an explicit numerical index, and you always have to use for when you don't actually have an iterable collection (e.g. iterating over a two-dimensional array grid in an upper triangle). There are some cases where you have a choice.

通常,当您没有一个显式的数字索引时,您总是必须使用foreach,而且当您实际上没有可迭代的集合时,您总是需要使用它(例如,在一个上三角形中迭代一个二维数组网格)。有些情况下你可以选择。

One could argue that for loops can be a little more difficult to maintain if magic numbers start to appear in the code. You should be right to be annoyed at not being able to use a for loop and have to build a collection or use a lambda to build a subcollection instead just because for loops have been banned.

有人可能会说,如果代码中出现了不可思议的数字,那么for循环维护起来会有点困难。您应该对不能使用for循环感到愤怒,并且必须构建一个集合或者使用lambda来构建一个子集合,而不是因为for循环被禁止。

#26


3  

Really screw with his head and go for an IQueryable .foreach closure instead:

真的用他的头去拧一拧,然后去找一个易趣的。

myList.ForEach(c => Console.WriteLine(c.ToString());

myList。ForEach(c = > Console.WriteLine(c.ToString());

LOL

哈哈

#27


2  

I wouldn't expect anyone to find a "huge" performance difference between the two.

我不认为会有人发现两者之间存在“巨大”的性能差异。

I guess the answer depends on the whether the collection you are trying to access has a faster indexer access implementation or a faster IEnumerator access implementation. Since IEnumerator often uses the indexer and just holds a copy of the current index position, I would expect enumerator access to be at least as slow or slower than direct index access, but not by much.

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

Of course this answer doesn't account for any optimizations the compiler may implement.

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

#28


2  

Keep in mind that the for-loop and foreach-loop are not always equivalent. List enumerators will throw an exception if the list changes, but you won't always get that warning with a normal for loop. You might even get a different exception if the list changes at just the wrong time.

记住,for循环和foreachloop并不总是等价的。如果列表发生变化,列表枚举器将抛出一个异常,但是您不会总是使用正常的for循环获得该警告。如果列表在错误的时间发生变化,您甚至可能得到不同的异常。

#29


2  

It seems a bit strange to totally forbid the use of something like a for loop.

完全禁止使用for循环之类的东西似乎有点奇怪。

There's an interesting article here that covers a lot of the performance differences between the two loops.

这里有一篇有趣的文章,它涵盖了两个循环之间的许多性能差异。

I would say personally I find foreach a bit more readable over for loops but you should use the best for the job at hand and not have to write extra long code to include a foreach loop if a for loop is more appropriate.

我个人认为,对于for循环,我发现每一个都更容易读,但是您应该尽可能地使用手边的工作,而不必编写额外的长代码来包含foreach循环,如果for循环更合适的话。

#30


1  

I did test it a while ago, with the result that a for loop is much faster than a foreach loop. The cause is simple, the foreach loop first needs to instantiate an IEnumerator for the collection.

我不久前确实对它进行了测试,结果是for循环要比foreach循环快得多。原因很简单,foreach循环首先需要实例化集合的IEnumerator。