14

I work on an array that and I have to loop over it. First, I use lambda ForEach

Array
.ForEach<int>( array, ( int counter ) => {
    Console.WriteLine( counter ); 
} );

and then I use simple foreach. I find that simple foreach is so faster than lambda ForEach, but when i test it with generic lists, ForEach is faster than simple foreach.

why loop on array object with foreach is faster than lambda ForEach? Update: I test on array

4
  • Thing that you call lambda foreach in fact implement lazy evaluation, so there is a lot of extra code. Commented May 27, 2013 at 4:02
  • 14
    Show your test cases. Commented May 27, 2013 at 4:07
  • 1
    I found the opposite in my test Commented May 27, 2013 at 4:22
  • tested on array now, is faster for both, but lamda is still the winner by a bit Commented May 27, 2013 at 4:37

2 Answers 2

4

I edited Keith's code a bit - On my machine foreach performed about six times faster than Array.ForEach:

class Program
{
    static void Main(string[] args)
    {
        Benchmark(50);
    }

    private static void Benchmark(int iterations)
    {
        int[] list = Enumerable.Range(0, 100000000).ToArray();

        long sum = 0;
        for (int i = 0; i < iterations; i++)
        {
            sum += ArrayForeach(list);
        }

        Console.WriteLine("ForEach " + sum / iterations);

        sum = 0;
        for (int i = 0; i < iterations; i++)
        {
            sum += Foreach(list);
        }

        Console.WriteLine("foreach " + sum / iterations);
    }

    private static long Foreach(int[] list)
    {
        long total = 0;
        var stopWatch = Stopwatch.StartNew();
        foreach (var i in list)
        {
            total += i;
        }
        stopWatch.Stop();
        return stopWatch.ElapsedTicks;
    }

    private static long ArrayForeach(int[] list)
    {
        long total = 0;
        var stopWatch = Stopwatch.StartNew();
        Array.ForEach(list, x => total += x);
        stopWatch.Stop();
        return stopWatch.ElapsedTicks;
    }
}

On my machine (which might run a different CLR than others) it produces (in Release):

ForEach 695910  
foreach 123852  

In Debug:

ForEach 941030
foreach 845443
  • It shows that foreach enjoys some compiler optimizations, I guess mainly in accessing the list in memory.
  • In Debug, it looks like the overhead of running the lambda, and passing the number (by value) is responsible for the difference.

I suggest that someone with more time take a look with Reflector...

Sign up to request clarification or add additional context in comments.

1 Comment

Nice test. My results: ForEach 1719909 foreach 386685
3

I find the lambda faster in my testing. Copy pasting MSDNs stopwatch code and decorating it with two versions of iterating a List.... ( I also changed the order of which test goes first, and I get the same timings). The Linq based iteration with a lambda goes faster.

Lambda  00:00:00.49
foreach 00:00:00.58

and the code..

var list = Enumerable.Range(0, 100000000).ToArray();
        var total = 0;
        var stopWatch = new Stopwatch();
        stopWatch.Start();
        Array.ForEach(list, x => total += x);

        stopWatch.Stop();
        TimeSpan ts = stopWatch.Elapsed;
        string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
            ts.Hours, ts.Minutes, ts.Seconds,
            ts.Milliseconds / 10);
        Console.WriteLine("RunTime " + elapsedTime);


        stopWatch = new Stopwatch();
        stopWatch.Start();
        foreach (var i in list)
        {
            total += i;
        }      
        stopWatch.Stop();
        // Get the elapsed time as a TimeSpan value.
        ts = stopWatch.Elapsed;

        // Format and display the TimeSpan value. 
        elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
            ts.Hours, ts.Minutes, ts.Seconds,
            ts.Milliseconds / 10);
        Console.WriteLine("RunTime " + elapsedTime);            

2 Comments

faster for both, but lambda still wins
how much faster? Mind exposing the detailed figures in the updated post?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.