مقایسه بین حلقه های تکرار (Lambda ForEach و for و foreach)
نویسنده: مسعود پاکدل
تاریخ: ۱۳۹۲/۰۳/۰۵ ۲۳:۴۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
var ListOfNumber = new List<int>() { 100, 200, 300 , 400 , 500 };
for ( int i = 0 ; i < ListOfNumber.Count ; i++ )
{
Console.WriteLine( ListOfNumber[i] );
}var ListOfNumber = new List<int>() { 100, 200, 300 , 400 , 500 };
for ( int i = 0 ; i < 5 ; i++ )
{
Console.WriteLine( ListOfNumber[i] );
}var ListOfNumber = new List<int>() { 100, 200, 300 , 400 , 500 };
foreach ( var number in ListOfNumber )
{
Console.WriteLine( number );
}var ListOfNumber = new List<int>() { 100, 200, 300 , 400 , 500 };
ListOfNumber.ForEach( number =>
{
Console.WriteLine( number );
});| تعداد تکرار | #1 for با استفاده از متغیر Count لیست | #2 for-استفاده از متغیر | #3 foreach | #4 Lambda ForEach |
|
1000 | 0.000008 | 0.000007 | 0.000014 | 0.000012 |
| 2000 | 0.000014 | 0.000013 | 0.000026 | 0.000022 |
| 3000 | 0.000019 | 0.000016 | 0.000036 | 0.000028 |
| 4000 | 0.000024 | 0.000022 | 0.000047 | 0.000035 |
| 5000 | 0.000029 | 0.000025 | 0.000058 | 0.000043 |
| 10,000 | 0.000059 | 0.000047 | 0.000117 | 0.000081 |
| 20,000 | 0.000128 | 0.000093 | 0.000225 | 0.000161 |
| 30,000 | 0.000157 | 0.000141 | 0.000336 | 0.000233 |
| 40,000 | 0.000221 | 0.000180 | 0.000442 | 0.000310 |
| 50,000 | 0.000263 | 0.000236 | 0.000553 | 0.000307 |
| 100,000 | 0.000530 | 0.000443 | 0.001103 | 0.000773 |
| 200,000 | 0.001070 | 0.000879 | 0.002194 | 0.001531 |
| 300,000 | 0.001641 | 0.001345 | 0.003281 | 0.002308 |
| 400,000 | 0.002233 | 0.001783 | 0.004388 | 0.003083 |
| 500,000 | 0.002615 | 0.002244 | 0.005521 | 0.003873 |
| 1,000,000 | 0.005303 | 0.004520 | 0.011072 | 0.007767 |
| 2,000,000 | 0.010543 | 0.009074 | 0.022127 | 0.015536 |
| 3,000,000 | 0.015738 | 0.013569 | 0.033186 | 0.023268 |
| 4000,000 | 0.021039 | 0.018113 | 0.044335 | 0.031188 |
| 5000,000 | 0.026280 | 0.022593 | 0.055521 | 0.038793 |
| 10,000,000 | 0.052528 | 0.046090 | 0.111517 | 0.078482 |
پس هر گاه قصد اجرای حلقه ForEach رو برای لیست دارید و سرعت اجرا هم براتون اهمیت داره بهتره که از Lambda ForEach استفاده کنید. حالا به کد زیر دقت کنید:
int[] arrayOfNumbers = new int[] {100 , 200 , 300 , 400 , 500 };
Array.ForEach<int>( arrayOfNumbers, ( int counter ) => { Console.WriteLine( counter ); } );Stopwatch sw = Stopwatch.StartNew();
var ListOfNumber = new List<int>() { 100, 200, 300 , 400 , 500 };
for ( int i = 0 ; i < ListOfNumber.Count ; i++ )
{
Console.WriteLine( ListOfNumber[i] );
}
sw.Stop();
Console.WriteLine("Total time (ms): {0}", (long) sw.ElapsedMilliseconds);public void ForEach(Action<T> action)
{
if (action == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
for (int index = 0; index < this._size; ++index)
action(this._items[index]);
}public static void ForEach<T>(T[] array, Action<T> action)
{
if (array == null)
throw new ArgumentNullException("array");
if (action == null)
throw new ArgumentNullException("action");
for (int index = 0; index < array.Length; ++index)
action(array[index]);
}() => { int a = 1; }long Sum(List<int> intList)
{
long result = 0;
foreach (int i in intList)
result += i;
return result;
}long Sum(List<int> intList)
{
long result = 0;
List<T>.Enumerator enumerator = intList.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
int i = enumerator.Current;
result += i;
}
}
finally
{
enumerator.Dispose();
}
return result;
}"این آزمایشات رو اگر در هر سیستم دیگر با هر Config اجرا کنید نتیجه کلی تغییر نخواهد کرد و فقط از نظر زمان اجرا تفاوت خواهیم داشت نه در نتیجه کلی."
static void Main(string[] args)
{
//Action<int> func = Console.WriteLine;
Action<int> func = number => number++;
do
{
try
{
Console.Write("Iteration: ");
var iterations = Convert.ToInt32(Console.ReadLine());
Console.Write("Loop Type (for:0, foreach:1, List.ForEach:2, Array.ForEach:3): ");
var loopType = Console.ReadLine();
switch (loopType)
{
case "0":
Console.WriteLine("FOR loop test for {0} iterations", iterations.ToString("0,0"));
TestFor(iterations, func);
break;
case "1":
Console.WriteLine("FOREACH loop test for {0} iterations", iterations.ToString("0,0"));
TestForEach(iterations, func);
break;
case "2":
Console.WriteLine("LIST.FOREACH test for {0} iterations", iterations.ToString("0,0"));
TestListForEach(iterations, func);
break;
case "3":
Console.WriteLine("ARRAY.FOREACH test for {0} iterations", iterations.ToString("0,0"));
TestArrayForEach(iterations, func);
break;
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Console.Write("Continue?(Y/N)");
Console.WriteLine("");
} while (Console.ReadKey(true).Key != ConsoleKey.N);
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
static void TestFor(int iterations, Action<int> func)
{
StartupTest(func);
var watch = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
func(i);
}
watch.Stop();
ShowResults("for loop test: ", watch);
}
static void TestForEach(int iterations, Action<int> func)
{
StartupTest(func);
var list = Enumerable.Range(0, iterations);
var watch = Stopwatch.StartNew();
foreach (var item in list)
{
func(item);
}
watch.Stop();
ShowResults("foreach loop test: ", watch);
}
static void TestListForEach(int iterations, Action<int> func)
{
StartupTest(func);
var list = Enumerable.Range(0, iterations).ToList();
var watch = Stopwatch.StartNew();
list.ForEach(func);
watch.Stop();
ShowResults("list.ForEach test: ", watch);
}
static void TestArrayForEach(int iterations, Action<int> func)
{
StartupTest(func);
var array = Enumerable.Range(0, iterations).ToArray();
var watch = Stopwatch.StartNew();
Array.ForEach(array, func);
watch.Stop();
ShowResults("Array.ForEach test: ", watch);
}
static void StartupTest(Action<int> func)
{
// clean up
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
// warm up
func(0);
}
static void ShowResults(string description, Stopwatch watch)
{
Console.Write(description);
Console.WriteLine(" Time Elapsed {0} ms", watch.ElapsedMilliseconds);
}