Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.Net - When is List<T>.ForEach prefered over a standard foreach loop?

The generic list class has a .ForEach(Action<T> action) method. Now i've done some simple timings of how they both perform and it seems that the generic ForEach is the poorer performer. The (Snippet Compiler Friendly) code is below -

public static class timer{
    public static long foreachloop = 0;
    public static long Gforeachloop = 0;}

public class something{
    public List<string> myStrings = new List<string>();

    public something()
    {
        for(int i = 1; i<=5000000;i++)
        {
            myStrings.Add(i.ToString());
        }
    }}

public class cls1{
    private static List<string> Strings = new List<string>();
    private static List<string> OtherStrings = new List<string>();

    public static void RunSnippet()
    {
        something s = new something();

        Stopwatch watch = new Stopwatch();
        watch.Start();
        foreach(string x in s.myStrings)
        {
            Strings.Add(x);
        }
        watch.Stop();
        timer.foreachloop = watch.ElapsedMilliseconds;

        watch.Reset();
        watch.Start();

        s.myStrings.ForEach(delegate(string n){OtherStrings.Add(n);});

        s.myStrings.Clear();

        watch.Stop();
        timer.Gforeachloop = watch.ElapsedMilliseconds;

        WL("FOREACH-"+timer.foreachloop + ",Count = " + Strings.Count);
        WL("GFOREACH-"+timer.Gforeachloop + ",Count = " + OtherStrings.Count);
    }

    #region Helper methods

    public static void Main()
    {
        try
        {
            RunSnippet();
        }
        catch (Exception e)
        {
            string error = string.Format("---\nThe following error occurred while executing the snippet:\n{0}\n---", e.ToString());
            Console.WriteLine(error);
        }
        finally
        {
            Console.Write("Press any key to continue...");
            Console.ReadKey();
        }
    }

    private static void WL(object text, params object[] args)
    {
        Console.WriteLine(text.ToString(), args);   
    }

    private static void RL()
    {
        Console.ReadLine(); 
    }

    private static void Break() 
    {
        System.Diagnostics.Debugger.Break();
    }

    #endregion
}

FOREACH comes out at 177ms and GFOREACH at 707ms.

Now I'm guessing there's a good reason for using it but i just can't think of one. Clearly performance isn't the reason so the question is when would it be the best option?

Thanks in advance.

like image 501
EightyOne Unite Avatar asked Aug 31 '25 16:08

EightyOne Unite


1 Answers

This blog post from Eric Lippert gives the background:

http://blogs.msdn.com/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx

He's talking about the common suggestion of an extension method to do the same thing for IEnumerable<T>, but the philosophical objection applies to List<T>.ForEach as well.

This suggests that maybe that method was never such a good idea, although it looks "cool". It's clearer to just use foreach.

I've suggested that such methods can be thought of as a fix for the classic closure-over-loop-variable bug.

But in practice I've just got better at spotting such bugs.

like image 118
Daniel Earwicker Avatar answered Sep 03 '25 01:09

Daniel Earwicker