Friday 30 December 2011

C# Jagged Array Examples

You need to evaluate jagged arrays in your C# programs. You have several rows of data, such as integers, and want to store them together in a single data structure. Jagged arrays are ideal for this, and this document has some examples and discussion, with code in the C# programming language.

Example

Here we see some example code that shows you how to use jagged arrays in different ways. The following code is a short but complete program you can run in a console project. It creates an array and sets values in it, then prints out the result at the end.
Example jagged array program [C#]

using System;

class Program
{
    static void Main()
    {
 // Declare local jagged array with 3 rows.
 int[][] jagged = new int[3][];

 // Create a new array in the jagged array, and assign it.
 jagged[0] = new int[2];
 jagged[0][0] = 1;
 jagged[0][1] = 2;

 // Set second row, initialized to zero.
 jagged[1] = new int[1];

 // Set third row, using array initializer.
 jagged[2] = new int[3] { 3, 4, 5 };

 // Print out all elements in the jagged array.
 for (int i = 0; i < jagged.Length; i++)
 {
     int[] innerArray = jagged[i];
     for (int a = 0; a < innerArray.Length; a++)
     {
  Console.Write(innerArray[a] + " ");
     }
     Console.WriteLine();
 }
    }
}

Output

"1 2"
"0"
"3 4 5"
Description. It declares a jagged array. The word 'jagged' doesn't even exist in the C# language, meaning that you don't need to use this word in your code. Jagged is just a descriptive variable name I use.
Initializations used. It initializes some values in the jagged array. There are lots of square brackets. This is very different from a 2D array, which uses commas instead of pure brackets.
Assigning jagged arrays. It assigns an array at the second index. Above you should see that indexes in the array are assigned to new int[] arrays. This is because the jagged array only allocates the list of empty references to arrays at first. You have to make your own arrays to put in it. We see the array initializer syntax here, which is less verbose than some other ways.
Looping over jagged arrays. You will want to examine each item in the jagged array. We must call Length first on the array of references, and then again on each inner array. The Console calls above are just for the example.
Two-dimensional (2D)

2D arrays

Here we will look at how you can choose between jagged arrays and 2D arrays. First, ask yourself the question: will every row in my collection have the same number of elements? If so, you can consider 2D arrays, but often you have varying numbers of elements.
Performance notes. Second, jagged arrays are faster and have different syntax. They are faster because they use the "newarr", vector IL calls internally. The boost is because they are optimized for starting at 0 indexes. Here is some code I compared in IL Disassembler.
Method that is reflected for MSIL test [C#]

private static void CompareIL()
{
    int[,] twoD = new int[1, 1]; // 1 x 1 array

    twoD[0, 0] = 1;

    int[][] jag = new int[1][];

    jag[0] = new int[1];
    jag[0][0] = 1; // 1 x 1 jagged array
}
Jagged array intermediate language in Visual StudioChoosing the syntax. Whichever array type you choose, don't select it because of the syntax. It is important to know that the pairs of brackets indicate "jagged," and the comma in the brackets means "2D".
Separate rows in arrays. You can allocate different arrays for each row in jagged arrays separately, which means your program must use 1D arrays in parts.

Parameters

You can use the type of the jagged array in method signatures in the C# language to use jagged arrays as parameters. You can use the same syntax as we saw above. They will be passed as references, which is important because it eliminates most copying. Only the reference is copied on each function call.
Performance optimization

Benchmark

The .NET runtime has optimizations for this specific case, and for some reason the 2D array cannot take advantage of them. My opinion is that you should always use jagged arrays when possible. They have substantial optimizations in the intermediate language level.
2D array code benchmarked [C#]

// 2D array of 100 x 100 elements.
for (int a = 0; a < 100; a++)
{
    for (int x = 0; x < 100; x++)
    {
 int c = a1[a, x];
    }
}

Jagged array code benchmarked [C#]

// Jagged array of 100 x 100 elements.
for (int a = 0; a < 100; a++)
{
    for (int x = 0; x < 100; x++)
    {
 int c = a2[a][x];
    }
}

Results

2D array looping:      4571 ms 
Jagged array looping:  2864 ms  [faster]

Summary

We saw how you can use jagged arrays in your C# programs. Jagged arrays are fast and easy to use once you learn the slightly different syntax. Prefer them to 2D arrays when performance is a consideration, and they are not more complex more to use. Investigating IL can be useful for understanding .NET internals.

No comments:

Post a Comment

Total Pageviews