Arrays in .NET – part IV

Today I’m going to to something which I really don’t like: I’m going to show you how to create non-zero lower bound arrays (aka, non-zero-based arrays). Before going on, I must say that I find it hard to justify the creation of these types of arrays. Anyways, since I’m covering arrays, I guess I must really show some code that illustrates its usage in C#. The Array class offers a static CreateInstance method which we can use to create arrays. There are several overloads, but we’re interested in the one which allow us to specify the lower bound and number of elements in each dimension. The following snippet shows how to create a single dimension array which can hold 2 elements on positions 10 and 11:

var ints = Array.CreateInstance(
    typeof(Int32), //type
    new[] { 2 }, //number of elements in each dimension
    new[] { 10 }); //first index in each dimension
ints.SetValue( 10, 10 );
ints.SetValue( 100, 11 );
Console.WriteLine( ints.GetValue( 11 ) );

As you can see, the CreateInstance method receives three parameters:

  • The first, identifies the type of each item that will be stored in the array.
  • The second is an array which indicates the number of elements stored in each dimension. Since we only have one one dimension, we pass only the number of items for that single dimension.
  • The third parameter identifies the starting index (ie, the lower bound) of each dimension (in this case, the array starts at index 10).

Internally, the CreateInstance method will allocate enough memory for the array, it will also keep the information about the bounds and dimensions and it will return an Array instance. As you can see, returning an Array instance means using the instance GetValue and SetValue methods for reading and writing values to our array…at least, that’s what we need to do in C#. Interestingly, we can use the traditional syntax for accessing items of a multi-dimension non-zero-based array:

var ints = (Int32[,]) Array.CreateInstance(
    typeof(Int32), //type
    new[] { 2,4 }, //number of elements in each dimension
    new[] { 10, 20 }); //first index in each dimension
ints[10, 20] = 10;//put value in first position

If you’re creating arrays where you don’t control the lower and upper bound indexes, then you should probably resort to the GetUpperBound and GetLowerBound methods. In the next snippet, I use these methods for enumerating all the items stored in the ints array:

for( Int32 i = ints.GetLowerBound( 0 ),
        firstDimUpper = ints.GetUpperBound( 0 );
        i < firstDimUpper ;
        i++ ) {
    for(Int32 j = ints.GetLowerBound( 1 ),
        secondDimUpper = ints.GetUpperBound( 1 );
        j < secondDimUpper;
        j++ ) {

As I said, using non-zero-based arrays is one of those things you shouldn’t really do. For starters, they have worst performance that the traditional zero-based arrays. And there are several reasons that justify this behavior. In fact, if you’re after performance, then you should use only single-dimension zero-based arrays. For starters, there are special IL instructions that the compiler uses for accessing items in these arrays that will make the JIT emit optimized code. When you’re using a single dimension zero-based array, the JIT can hoist the index checking code in loop, making that validation run only once, at the beginning of that loop.

This hoisting optimization doesn’t happen with non single dimension zero-based arrays (in practice, this means that each array item access will only be allowed after checking if the specified index is valid). Besides that, the JIT will have to subtract the array’s lower bound position to the specified index to get the item you’re requesting (notice that this is also done for multi-dimension zero-based arrays). These issues make me believe that using non-zero based arrays in .NET isn’t really a thing which you want to do often. And I have done just that in these last years…

And I guess that’s it for now. Stay tuned for more.


~ by Luis Abreu on May 20, 2011.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: