CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

David Hayden [MVP C#]

         .NET Tutorials, Patterns, and Practices

for and foreach loops - Compiler Optimizations Regarding Bounds Checking

Last night I listened to most of Brad Adams presentation on Rich Type System as part of his series on Designing .NET Libraries.  All the presentations can be downloaded off-line by the way.

He briefly mentioned some of the optimizations done by the compiler regarding for loops and bounds checking in Arrays.  I don't think we can assume the same can be said of ArrayLists and other collections, but I don't know for sure.  I also read this in Effective C#, which is why I thought I would mention it since it was rather cool to recently get this information in two places.

Essentially, the JIT compiler has been trained to look at certain for loop code structures and based on them, optimize the underlying code being emitted.

The following are two different for loops that accomplish the same thing.  Loop #1 "caches" the length of the array in a variable and uses the variable within the for loop to signify the end of the loop.  The thought here is that by not accessing the Length property of the array on each and every loop, we may increase performance.  Loop #2 just uses the Length property of the array to signify the end of the loop.

Loop 1: Caching Array Length
using System;
using System.Collections;

public class MyClass
{
    public static void Main()
    {
        int[] myInts = new int[5] {1,2,3,4,5};
        
        int totalLoops = myInts.Length;
        for (int i=0; i < totalLoops; i++)
            Console.WriteLine(myInts[i].ToString());
            
        Console.ReadLine();
    }
}

 

Loop 2: Using Length Property
using System;
using System.Collections;

public class MyClass
{
    public static void Main()
    {
        int[] myInts = new int[5] {1,2,3,4,5};
        
        for (int i=0; i < myInts.Length; i++)
            Console.WriteLine(myInts[i].ToString());
            
        Console.ReadLine();
    }
}

As luck would have it, Loop #2 is a for loop code structure that is looked for by the JIT compiler in .NET 1.1.  It determines that this loop will never attempt to access an element not bounded by the array and thus emits a more performant loop that either reduces or eliminates the bounds checking.  Brad didn't elaborate, but I assume it just eliminates the bounds checking altogether.  Trying to be "clever" in Loop #1 in .NET 1.1 actually costs you in terms of performance, albeit it may not be noticeable in a lot of situations.

In my development, I always use the foreach loop.  I assume it also emits a more performant loop by the compiler as it will only iterate within the bounds of the array as well.  It used to be, in .NET 1.0, that the foreach loop was less performant than the for loop, but this isn't the case anymore.

The other benefit you get from the foreach loop is that you don't have to specify the Length property for Arrays and the Count property for ArrayLists, for example, as foreach just iterates using the IEnumerator interface supported by these classes.  Thus, if you decide to change the type of collection from an Array to an ArrayList, you don't have to change Length to Count as you would in all your for loops.


Published Feb 27 2005, 11:14 AM by David Hayden
Filed under:

Comments

Brendan Tompkins said:

This is good to know. I almost always use a foreach, unless I'm modifying the collection somehow within the loop, which throws runtime errors.
# February 27, 2005 1:50 PM

TrackBack said:

# March 3, 2005 6:33 PM
Check out Devlicio.us!

This Blog

Syndication

News

CodeBetter.Com Home