The case of the slow for-loop

We recently had a problem with a page in an MVC application that was very slow, it took minutes before the server finished creating it. It turned out that it was this for-loop that caused the problem:

for (int i = 0; i < Model.Deltagare.Count(); i++)
{
  var deltagare = Model.Deltagare.ElementAt(i);
  ...
}

where Model.Deltagare is an IEnumerable. This is a common construct when you need to track the loop index for some reason but it turns out that its use really should be discouraged. The problem is that ElementAt(i) can take a really long time depending on the underlying list type of the enumerable. If it’s an array, it’s really quick, but in our case it was a System.Linq.Enumerable.WhereSelectListIterator and apparently ElementAt(i) had to traverse the enumerator from the start each time it was called. That’s not what you want to use an iterator for…

We changed the above loop to a foreach-loop instead, so that the iterator can be used more naturally:

int i;
foreach (var deltagare in Model.Deltagare)
{
  ...
  i++;
}

The duration of our loop went from about 10 minutes to 1 second for a list of about 6000 items.

Lesson learned.

/Emil

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.

This site uses Akismet to reduce spam. Learn how your comment data is processed.