You may think this is a superfluous post as there are already many posts out there on web discussing about performance measures when using For or Foreach. Some of them are:
For vs Foreach Performance.
Which loop is faster for or foreach.
and many more…
for (int i = 0; i < collection.Count; ++i)
{
// Work on a collection[i].
}
vs
foreach (var item in collection)
{
// Work on an item.
}
By looking at title of the post, if you think I’m going to get into same debate here, then wait! I’ve something else to say. It’s still for vs foreach. However, rather than comparing inherent performance of for vs foreach, I’m going to discuss how things could go wrong when a programmer incorrectly uses language construct for the given context.
Recently I’ve been reviewing a piece code doing some complex work on a collection:
foreach (var element in collection)
{
int firstIndex = collection.IndexOf(element);
int secondIndex = 0;
foreach (var anotherElement in collection)
{
if (secondIndex > firstIndex)
{
// Use element and anotherElement for some operation.
}
++secondIndex;
}
}
You’re a reviewer of this code – now without reading this article further, check what’s wrong with this code snippet.
I was just wondering what is this code doing for a while. At first, only optimization I could think of was to avoid executing ++secondIndex once secondIndex > firstIndexexpression is true i.e. secondIndex will always be larger for subsequent iterations. Just after few seconds I said, ah – this is wrong! horrible code. There is another hidden loop here which is nothing but a call to IndexOf. It is a linear search over the collection and time complexity of the algorithm is O(n). Using for loop here will be much faster and much more readable.
for (int i = 0; i < collection.Count; ++i)
{
for (int j = i + 1; j < collection.Count; ++j)
{
// Use collection[i] and collection[j] here for some operation.
}
}
Conclusion
Never use foreach when you really need to use for. That is if you need to access indexes of the collection always use for.
Top comments (2)
Can IndexOf return -1? If so, you may have an infinite loop on your hands.
Indeed!