What Are the Differences Between a Multidimensional Array and an Array of Arrays in C#

What are the differences between a multidimensional array and an array of arrays in C#?

Array of arrays (jagged arrays) are faster than multi-dimensional arrays and can be used more effectively. Multidimensional arrays have nicer syntax.

If you write some simple code using jagged and multidimensional arrays and then inspect the compiled assembly with an IL disassembler you will see that the storage and retrieval from jagged (or single dimensional) arrays are simple IL instructions while the same operations for multidimensional arrays are method invocations which are always slower.

Consider the following methods:

static void SetElementAt(int[][] array, int i, int j, int value)
{
array[i][j] = value;
}

static void SetElementAt(int[,] array, int i, int j, int value)
{
array[i, j] = value;
}

Their IL will be the following:

.method private hidebysig static void  SetElementAt(int32[][] 'array',
int32 i,
int32 j,
int32 'value') cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: ldelem.ref
IL_0003: ldarg.2
IL_0004: ldarg.3
IL_0005: stelem.i4
IL_0006: ret
} // end of method Program::SetElementAt

.method private hidebysig static void SetElementAt(int32[0...,0...] 'array',
int32 i,
int32 j,
int32 'value') cil managed
{
// Code size 10 (0xa)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: ldarg.2
IL_0003: ldarg.3
IL_0004: call instance void int32[0...,0...]::Set(int32,
int32,
int32)
IL_0009: ret
} // end of method Program::SetElementAt

When using jagged arrays you can easily perform such operations as row swap and row resize. Maybe in some cases usage of multidimensional arrays will be more safe, but even Microsoft FxCop tells that jagged arrays should be used instead of multidimensional when you use it to analyse your projects.

What's the difference between arrays of arrays and multidimensional arrays?

Take .NET arrays which illustrate this nicely:

C# has a distinction between jagged arrays which are defined in a nested fashion:

int[][] jagged = new int[3][];

Each nested array can have a different length:

jagged[0] = new int[3];
jagged[1] = new int[4];

(And note that one of the nested arrays isn’t initialised at all, i.e. null.)

By contrast, a multidimensional array is defined as follows:

int[,] multidim = new int[3, 4];

Here, it doesn’t make sense to talk of nested arrays, and indeed trying to access multidim[0] would be a compile-time error – you need to access it providing all dimensions, i.e. multidim[0, 1].

Their types are different too, as the declarations above reveal.

Furthermore, their handling is totally different. For instance, you can iterate over the above jagged array with an object of type int[]:

foreach (int[] x in jagged) …

but iterating over a multidimensional array is done with items of type int:

foreach (int x in multidim) …

Conceptually, a jagged array is an array of arrays (… of arrays of arrays … ad infinitum) of T while a multidimensional array is an array of T with a set access pattern (i.e. the index is a tuple).

the difference between [,] and [][] in C#

[,] form creates rectangular two dimensional array. When you specify the dimensions you will get a two dimensional matrix of those sizes. All its elements are initialized to the default value of the element type.

int[,] array = new int[4, 2];

Memory-wise, the array is stored as a single block in memory (of size width*height). Accessing an element is a little slower and the runtime does more expensive operations - see http://blog.mischel.com/2013/05/08/are-jagged-arrays-faster-than-rectangular-arrays/

[][] is called jagged array and it is basically an array of arrays. When you create it, you first only specify the size of the first dimension:

int[][] jaggedArray = new int[3][];

Now you have to create a new array for each of the rows manually (they are initially null)

jaggedArray[0] = new int[10];
jaggedArray[1] = new int[6];

The advantage of this is that each row can have a different length.

In memory, each of the rows is stored in a different location, but accessing a specific element is ultimately faster, because it just requires the runtime to find the pointer to the row array in the base array and then find the requested element as in a normal array.

Multidimensional Array [][] vs [,]

One is an array of arrays, and one is a 2d array. The former can be jagged, the latter is uniform.

That is, a double[][] can validly be:

double[][] x = new double[5][];

x[0] = new double[10];
x[1] = new double[5];
x[2] = new double[3];
x[3] = new double[100];
x[4] = new double[1];

Because each entry in the array is a reference to an array of double. With a jagged array, you can do an assignment to an array like you want in your second example:

x[0] = new double[13];

On the second item, because it is a uniform 2d array, you can't assign a 1d array to a row or column, because you must index both the row and column, which gets you down to a single double:

double[,] ServicePoint = new double[10,9];

ServicePoint[0]... // <-- meaningless, a 2d array can't use just one index.

UPDATE:

To clarify based on your question, the reason your #1 had a syntax error is because you had this:

double[][] ServicePoint = new double[10][9];

And you can't specify the second index at the time of construction. The key is that ServicePoint is not a 2d array, but an 1d array (of arrays) and thus since you are creating a 1d array (of arrays), you specify only one index:

double[][] ServicePoint = new double[10][];

Then, when you create each item in the array, each of those are also arrays, so then you can specify their dimensions (which can be different, hence the term jagged array):

ServicePoint[0] = new double[13];
ServicePoint[1] = new double[20];

Hope that helps!

multidimensional array definition in c# (difference and applications)

array1 is called a reference to a multidimensional array; array2 is a reference to a jagged array.

The first one is designed to store rectangular data which is not sparse and the number of elements in the dimensions are almost the same. You can initialize it like:

// Two-dimensional array.
int[,] array1= new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };

In the latter case which is also called array of array the elements can be of different dimensions and sizes. Some times it is memory optimized to store sparse 2d data in the RAM. You can initialize it like:

int[][] array2= new int[][] 
{
new int[] { 1, 3, 5, 7, 9 },
new int[] { 0, 2, 4, 6 },
new int[] { 11, 22 }
};

Absolutely the usage is depends on you requirements and purposes. You can review these 1, 2.

Why we have both jagged array and multidimensional array?

  1. A jagged array is an array-of-arrays, so an int[][] is an array of int[], each of which can be of different lengths and occupy their own block in memory. A multidimensional array (int[,]) is a single block of memory (essentially a matrix).

  2. You can't create a MyClass[10][20] because each sub-array has to be initialized separately, as they are separate objects:

    MyClass[][] abc = new MyClass[10][];

    for (int i=0; i<abc.Length; i++) {
    abc[i] = new MyClass[20];
    }

    A MyClass[10,20] is ok, because it is initializing a single object as a matrix with 10 rows and 20 columns.

  3. A MyClass[][,][,] can be initialized like so (not compile tested though):

    MyClass[][,][,] abc = new MyClass[10][,][,];

    for (int i=0; i<abc.Length; i++) {
    abc[i] = new MyClass[20,30][,];

    for (int j=0; j<abc[i].GetLength(0); j++) {
    for (int k=0; k<abc[i].GetLength(1); k++) {
    abc[i][j,k] = new MyClass[40,50];
    }
    }
    }

Bear in mind, that the CLR is heavily optimized for single-dimension array access, so using a jagged array will likely be faster than a multidimensional array of the same size.



Related Topics



Leave a reply



Submit