3

ジェネリック リスト クラスには.ForEach(Action<T> action)メソッドがあります。今、私は両方がどのように実行されるかについていくつかの簡単なタイミングを実行しましたが、一般的な ForEach の方がパフォーマンスが悪いようです。(スニペットコンパイラフレンドリー)コードは以下のとおりです -

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 は 177ms で、GFOREACH は 707ms で出てきます。

今、私はそれを使用する正当な理由があると推測していますが、私はそれを考えることができません. 明らかにパフォーマンスが理由ではないので、問題はいつ最適なオプションになるかということです。

前もって感謝します。

4

2 に答える 2

7

Eric Lippert のこのブログ投稿では、背景について説明しています。

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

彼は、 に対して同じことを行う拡張メソッドの一般的な提案について話していますIEnumerable<T>が、哲学的な反論は にも当てはまりList<T>.ForEachます。

これは、「かっこいい」ように見えますが、おそらくその方法はそれほど良い考えではなかったことを示唆しています。を使用する方が明確foreachです。

このようなメソッドは、従来のクロージャ オーバー ループ変数のバグの修正と見なすことができると提案しました。

しかし、実際には、そのようなバグを見つけるのが上手になりました。

于 2009-07-23T16:42:35.450 に答える
6

すっきり見えたら。

まったく冗談ではありません。本当に、私はそれを意味します。あなたのケースでは、より読みやすいスタイルを使用してください。たとえば、次のように各アイテムでメソッドを呼び出したいだけの場合:

list.ForEach(Console.WriteLine);

このスタイルの方が似合います。ただし、ループの本体として 100 行ある場合、またはネストされたループと制御フロー構造がある場合は、古いスタイルの方が見栄えがします。

于 2009-07-23T16:40:38.263 に答える