Welcome to MSDN Blogs Sign in | Join | Help

New Tricks (Thinking in C#)

Attending a great “Designing .NET Class Libraries” class run by Brad Abrams today.

I was surprised to see a coding pattern that I would commonly use in C++ and be told that was NOT the best way to do this in C#.

int len = array.Length();
for ( int i=0; i<len; i++ )
{
    array[i] = 0;
}

In C++, there's a performance gain in this example because the array Length() member is only called once and the value is cached for use inside the loop.

Apparently, because of how the JIT compiler unrolls loops and optimises bounds checking, the following pattern is going to produce more eficient code in C#, even though my C++ 'brain' says otherwise.

for ( int i=0; i<array.Length(); i++ )
{
    array[i] = 0;
}

This highlights my lack of C# knowledge since my initial response is to fallback to what I know best, which is C++. This is perfectly natural, since I'm still working at becoming an expert at C#, and the ease of use gained by C# and .NET comes with a price - handing over more responsibility to the C# compiler and .NET libraries. In making the move to C#, I need to leave behind my knowledge of Visual C++ optimization techniques and learn more about what the C# compiler is doing under the cover.

I need to learn some new tricks. I'm going to start by going over to the MSDN library and reading some of the performance related .NET Development articles, such as “Performance Considerations for Run-Time Technologies in the .NET Framework“.

Published Thursday, April 01, 2004 6:30 PM by markda
Filed under:

Comments

# re: New Tricks (Thinking in C#)

Friday, April 02, 2004 3:09 AM by Jerry Pisk
It just goes to show you that writing code to outsmart a compiler is never a good idea. Just write code that's simple, easy to read and understand and maintain.

# re: New Tricks (Thinking in C#)

Friday, April 02, 2004 5:44 AM by Udi Dahan - The Software Simplist
There is one case where you have to be careful:

When looping over a collection, and you wish to perform a specific action on every element, but, as well, adding or removing items from the collection, then the behaviour you get won't be what you expect when using myCollection.Count.

eg:

for (int i=0; i < myCol.Count; i++)
myCol.Remove( myCol[i] );

instead do use the member variable:

int count = myCol.Count;
for ( int =0; i < count; i++ )
myCol.Remove( myCol[i] );

# re: New Tricks (Thinking in C#)

Friday, April 02, 2004 12:57 PM by markda
Good point - I don't know if the C# compiler can still optimize if you're performing actions on the array, since an array bounds error will occur when you attempt to access an element that has been removed.

Should your example be the other way round? If you're removing elements, you'll need to recalculate the array count each time to take account of the removal.

# re: New Tricks (Thinking in C#)

Monday, June 14, 2004 2:59 PM by Udi Dahan - The Software Simplist
You won't get an ArrayOutOfBoundsException because the value of myCol.Count is always accurate, even after removal in a loop. The point is that you're expecting to perform a certain action N times where N is the original number of elements in the collection. However, as the value of i increases, the value of myCol.Count decreases in this case.

If myCol.Count was originally 10, you would only go through the loop 5 times, which is not what you intended. This is a logic bug, which is one of the more difficult bugs to find, especially because the code compiles and, in fact, does do SOME of the work.

Just thought I'd save somebody else some grief.

# SQL Server 2005 Anticipation

Tuesday, November 30, 2004 5:29 PM by Frankie Fresh's Blog

# JIT optimizations on for loop with ar.Length constraint

Saturday, April 23, 2005 10:51 PM by Brad Abrams
A reader wrote in recently and asked me why the non-caching version of the following code was faster...
Anonymous comments are disabled
 
Page view tracker