Title: Compare loop performance in C#
The Code Project post FOREACH Vs. FOR (C#) examines the IL code created for a C# foreach loop and a for loop to compare loop performance. The author notices some unnecessary statements in the foreach loop and therefore concludes that it will be slower.
That's true as far as it goes, but I wanted to see just how big the difference was so I wrote this example to test loop performance. It uses the following code to compare the performance of foreach, for, and while loops. The looping code is highlighted in blue so it's easy to separate from the timing code.
private void btnGo_Click(object sender, EventArgs e)
{
Cursor = Cursors.WaitCursor;
txtForEach.Clear();
txtFor.Clear();
txtWhile.Clear();
txtForEach.Refresh();
txtFor.Refresh();
txtWhile.Refresh();
int num_items = int.Parse(txtArraySize.Text);
int num_trials = int.Parse(txtNumTrials.Text);
int[] array = new int[num_items];
int total = 0;
Stopwatch watch = new Stopwatch();
total = 0;
watch.Start();
for (int trial = 0; trial < num_trials; trial++)
{
foreach (int value in array)
{
total += value;
}
}
watch.Stop();
txtForEach.Text = watch.Elapsed.TotalSeconds.ToString("0.00");
txtForEach.Refresh();
total = 0;
watch.Reset();
watch.Start();
for (int trial = 0; trial < num_trials; trial++)
{
for (int i = 0; i < num_items; i++)
{
total += array[i];
}
}
watch.Stop();
txtFor.Text = watch.Elapsed.TotalSeconds.ToString("0.00");
txtFor.Refresh();
total = 0;
watch.Reset();
watch.Start();
for (int trial = 0; trial < num_trials; trial++)
{
int i = 0;
while (i < num_items)
{
total += array[i++];
}
}
watch.Stop();
txtWhile.Text = watch.Elapsed.TotalSeconds.ToString("0.00");
txtWhile.Refresh();
Cursor = Cursors.Default;
}
The picture at the top of this post shows that foreach was the fastest and for was slowest, contrary to the predictions in the Code Project article. Go figure.
At least that's how it worked in Visual Studio 2008. The picture on the right shows the same program running in Visual Studio 2022. Now the foreach loop is still the fastest but the for loop takes second place, and the while loop comes in third.
I want to make two points here. First, you can't depend on the exact timing of different language constructs because the language team may change they way are implemented in different versions. In this case Visual Studio 2022 probably implements the foreach and for differently than Visual Studio 2008 does so the timings changed. If you rely on one set of behaviors, you may be disappointed if it changes later.
The second point is that the differences in these speeds is ludicrously small. In the Visual Studio 2015 program, the total difference was 0.2 seconds but that was over 100,000 iterations through the loops. That means the difference is only 0.000002 seconds per iteration. Unless you plan on running a HUGE number of iterations, the difference won't matter.
In fact a real program would probably do more than just add up the values inside the loops. In that case the time spent performing those operations would be a much greater fraction of the total time than the tiny difference in loop speed. In other words, if performing a calculation 100,000 times takes 10 seconds, wasting 0.2 seconds on a for loop really isn't a big deal.
The moral is that you should pick the kind of loop that makes the code easiest to read and understand. I've never seen a project fail because performance was too slow by a few tenths of a second but I've seen several project fail because the code was too hard to read and debug.
Download the example to experiment with it and to see additional details.
|