In .NET, which loop runs faster, 'for' or 'foreach'?

前端 未结 30 1367
抹茶落季
抹茶落季 2020-11-22 04:25

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

Ever since I read that a for loop works faster than a foreach

相关标签:
30条回答
  • 2020-11-22 04:48

    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.

    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.

    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 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 (int i = 0; i < myCollection.Length, i++)
    
    0 讨论(0)
  • 2020-11-22 04:49

    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.

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

    0 讨论(0)
  • 2020-11-22 04:50

    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)?

    0 讨论(0)
  • 2020-11-22 04:50

    You can really screw with his head and go for an IQueryable .foreach closure instead:

    myList.ForEach(c => Console.WriteLine(c.ToString());
    
    0 讨论(0)
  • 2020-11-22 04:53

    you can read about it in Deep .NET - part 1 Iteration

    it's cover the results (without the first initialization) from .NET source code all the way to the disassembly.

    for example - Array Iteration with a foreach loop:

    and - list iteration with foreach loop:

    and the end results:

    0 讨论(0)
  • 2020-11-22 04:54

    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.

    enter image description here

    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,

    • Foreach loop with array.
    • For loop with list.
    • Foreach loop with list.

    See my test results and code below,

    enter image description here

    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);
        }
    
    0 讨论(0)
提交回复
热议问题