So what is faster: looping through a List<> with for or with foreach?

Today I’ll show you how to use BenchmarkDotNet with .Net Core to answer that question.

Let’s start:

1. Create a folder for your new project#


Open a command prompt an run:

1mkdir benchmark.for

2. Create the project#


1cd benchmark.for
2dotnet new console

3. Add the references to BenchmarkDotNet#


1dotnet add package BenchmarkDotNet -v 0.11.0
2dotnet restore

4. Replace the contents of Program.cs with the following code#


 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using BenchmarkDotNet.Attributes;
 5using BenchmarkDotNet.Running;
 6
 7namespace benchmark
 8{
 9    public class Program
10    {
11        public static void Main(string[] args)
12        {
13            // Use BenchmarkRunner.Run to Benchmark your code
14            var summary = BenchmarkRunner.Run<ForEachVsFor>();
15        }
16    }
17
18    // We are using .Net Core we are adding the CoreJobAttribute here.
19    [CoreJob(baseline: true)]
20    [RPlotExporter, RankColumn]
21    public class ForEachVsFor
22    {
23        private static Random random = new Random();
24        private List<int> list;
25
26        public static List<int> RandomIntList(int length)
27        {
28            int Min = 1;
29            int Max = 10;
30            return Enumerable
31                .Repeat(0, length)
32                .Select(i => random.Next(Min, Max))
33                .ToList();
34        }
35
36        // We wil run the the test for 3 diff list sizes
37        [Params(10, 100, 1000)]
38        public int N;
39
40        [GlobalSetup]
41        public void Setup()
42        {
43            list = RandomIntList(N);
44        }
45
46        // Foreach is ~2 times slower than for
47        [Benchmark]
48        public void Foreach()
49        {
50            int total = 0;
51            foreach (int i in list)
52            {
53                total += i;
54            }
55        }
56
57        // For is ~2 times faster than foreach
58        [Benchmark]
59        public void For()
60        {
61            int total = 0;
62            for (int i = 0; i < list.Count; i++)
63            {
64                total += list[i];
65            }
66        }
67    }
68}

5. Run the application and interpret the results#


Run the following command:

1dotnet run -c release

after a while you should expect an output like the following:

 1// * Summary *
 2
 3BenchmarkDotNet=v0.11.0, OS=Windows 10.0.17134.228 (1803/April2018Update/Redstone4)
 4Intel Core i5-6300U CPU 2.40GHz (Skylake), 1 CPU, 4 logical and 2 physical cores
 5Frequency=2437501 Hz, Resolution=410.2562 ns, Timer=TSC
 6.NET Core SDK=2.1.302
 7  [Host] : .NET Core 2.1.2 (CoreCLR 4.6.26628.05, CoreFX 4.6.26629.01), 64bit RyuJIT
 8  Core   : .NET Core 2.1.2 (CoreCLR 4.6.26628.05, CoreFX 4.6.26629.01), 64bit RyuJIT
 9
10Job=Core  Runtime=Core
11
12  Method |    N |        Mean |      Error |      StdDev |      Median | Scaled | Rank |
13-------- |----- |------------:|-----------:|------------:|------------:|-------:|-----:|
14 Foreach |   10 |    45.76 ns |  3.0062 ns |   8.8167 ns |    43.15 ns |   1.00 |    1 |
15         |      |             |            |             |             |        |      |
16     For |   10 |    18.14 ns |  0.4040 ns |   0.3968 ns |    18.04 ns |   1.00 |    1 |
17         |      |             |            |             |             |        |      |
18 Foreach |  100 |   503.16 ns |  9.9973 ns |  24.8968 ns |   501.49 ns |   1.00 |    1 |
19         |      |             |            |             |             |        |      |
20     For |  100 |   149.56 ns |  3.6317 ns |  10.1238 ns |   147.41 ns |   1.00 |    1 |
21         |      |             |            |             |             |        |      |
22 Foreach | 1000 | 2,611.51 ns | 51.7677 ns | 122.0225 ns | 2,596.29 ns |   1.00 |    1 |
23         |      |             |            |             |             |        |      |
24     For | 1000 | 1,406.77 ns | 28.3726 ns |  82.3140 ns | 1,391.04 ns |   1.00 |    1 |

So as you can see for performs much better than foreach when looping through a List<>!!!

Try changing the int type for a class and then working with it inside the loop and check the results. You’ll know what to do next time you need your application to run fast!

Please find all the code used in this post here.

Hope it helps!