.Net - 標準の foreach ループよりも List<T>.ForEach が優先されるのはどのような場合ですか?
-
19-09-2019 - |
質問
ジェネリックリストクラスには、 .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 は 177 ミリ秒、GFOREACH は 707 ミリ秒で出力されます。
今のところ、それを使用する正当な理由があると思いますが、それが思いつきません。明らかにパフォーマンスが理由ではないため、問題は、いつそれが最適な選択肢になるかということです。
前もって感謝します。
解決
Eric Lippert のこのブログ投稿では、背景を説明しています。
http://blogs.msdn.com/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx
彼は、同じことを行うための拡張メソッドの一般的な提案について話しています。 IEnumerable<T>
, 、しかし哲学的反論は以下に当てはまります。 List<T>.ForEach
同じように。
これは、その方法は「クール」に見えても、決して良いアイデアではなかった可能性があることを示唆しています。単に使用する方が明確です foreach
.
そのような方法は次のように考えることができると私は提案しました。 古典的なクロージャオーバーループ変数のバグの修正.
しかし実際には、私はそのようなバグを見つけるのが少しずつ上手になってきました。
他のヒント
それは滑らかな印象に見えます。
全くないジョーク。本当に、私はそれを意味します。あなたのケースでは、より読みやすいスタイルで行きます。たとえば、あなただけのように各項目のメソッドをコールする場合:
list.ForEach(Console.WriteLine);
このスタイルが良く似合います。ただし、ループ本体として100行を持っている場合、または古いスタイルが良く見える、ループおよび制御フロー構造を入れ子になっています。