.Net - 什么时候是List <T> .ForEach优先于标准的foreach循环?

Eig*_*ite 3 c# generics performance generic-list

通用列表类有一个.ForEach(Action<T> action)方法.现在我已经完成了一些关于它们如何表现的简单时间,似乎通用ForEach是较差的表演者.(Snippet Compiler Friendly)代码如下 -

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
}
Run Code Online (Sandbox Code Playgroud)

FOREACH出现在177ms,GFOREACH出现在707ms.

现在我猜这是使用它的一个很好的理由,但我想不出一个.显然性能不是原因,所以问题是何时它是最佳选择?

提前致谢.

Dan*_*ker 7

这篇来自Eric Lippert的博客文章给出了背景:

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

他正在讨论扩展方法的共同建议,即做同样的事情IEnumerable<T>,但哲学上的反对也适用List<T>.ForEach.

这表明也许这种方法从来都不是一个好主意,虽然它看起来很"酷".使用起来更清楚foreach.

我已经建议这样的方法可以被认为是对经典的闭环过程变量bug的修复.

但在实践中,我只是更好地发现了这样的错误.


Meh*_*ari 6

当它看起来更整洁.

根本不是开玩笑.真的,我的意思是.在您的情况下,使用更易读的样式.例如,如果您只想在每个项目上调用方法,例如:

list.ForEach(Console.WriteLine);
Run Code Online (Sandbox Code Playgroud)

这种风格更适合.但是,如果你有一百行作为循环体,或者你有嵌套循环和控制流结构,旧样式看起来更好.

  • 哦,我以为你的意思是*真正的*功能语言!:P (2认同)