tags:

views:

144

answers:

3

When creating a 3D array in C#, which is a better way to create it?

Array[a,b,c] or Array[a][b][c]?

Or is it just a matter of preference?

+7  A: 
  1. These are two fundamentally different constructs. If one suits your requirements better than the other, prefer it as a matter of course.

    Array[a,b,c] is a three dimensional, rectangular array. This means that all elements exist, but depending on your needs, may be sparsely populated. Array[a][b][c] is a three dimension jagged array, or an array of arrays of arrays.

  2. All things being equal, I believe I once read a source (That I considered authoritative at the time) that the jagged array is generally preferable to the rectangular array. I don't recall whether the reason was some sort of performance-related reason (caching?) or something else.

Greg D
That source was probably the .NET Framework Design Guidelines or the FXCop help file. Both prefer jagged arrays.
Jonathan Allen
Can someone explain why jagged array can be faster than multidimensional array?IMHO multidimensional array should be faster, because it is much easier to calculate exact address of an object that is stored in such array.
Tomek Tarczynski
Everyone says that jagged are faster but no one tells why :)
Poma
I would also be interested in knowing why jagged arrays are faster, and think an explanation tacked to this comment would be helpful to other users, thanks.
Soo
@soo, poma: see my answer below for an explanation ;)
stmax
A: 

If You want to have 'rectangular' array then Array[a,b,c] should be faster.
If you need some other shape then You should use Array[a][b][c] - in this case first row can contain for example 5 object, second 6 objects, and so on.

Tomek Tarczynski
a jagged Array[a][b][c] is faster
stmax
+4  A: 

rectangular arrays are easier to initialize, but jagged arrays are faster. the reason why jagged arrays are faster is because there are intermediate language instructions that directly support one dimensional arrays. compare the follow two disassemblies:

the c# method:

public static int A()
{
    int[,] a = new int[5, 5];
    return a[3, 4];
}

compiles to:

.method public hidebysig static int32 A() cil managed
{
    .maxstack 3
    .locals init (
        [0] int32[0...,0...] a)
    L_0000: ldc.i4.5 
    L_0001: ldc.i4.5 
    L_0002: newobj instance void int32[0...,0...]::.ctor(int32, int32)
    L_0007: stloc.0 
    L_0008: ldloc.0 
    L_0009: ldc.i4.3 
    L_000a: ldc.i4.4 
    L_000b: call instance int32 int32[0...,0...]::Get(int32, int32)
    L_0010: ret 
}

and the c# method:

public static int B()
{
    int[][] a = null;
    return a[3][4];
}

compiles to:

.method public hidebysig static int32 B() cil managed
{
    .maxstack 2
    .locals init (
        [0] int32[][] a)
    L_0000: ldnull 
    L_0001: stloc.0 
    L_0002: ldloc.0 
    L_0003: ldc.i4.3 
    L_0004: ldelem.ref 
    L_0005: ldc.i4.4 
    L_0006: ldelem.i4 
    L_0007: ret 
}

as you can see the first method uses a (slow) method call to get the value of an array item:

call instance int32 int32[0...,0...]::Get(int32, int32)

while the second one uses the (much faster) ldelem IL instructions:

L_0004: ldelem.ref 
L_0005: ldc.i4.4 
L_0006: ldelem.i4 

this was compiled using VS2008 in release mode. benchmark shows that the jagged array version is about 25% faster than the rectangular array version (access using sequential as well as random indices).

stmax
Thanks, that is satysfying answer, but counterintuitive for me :)
Tomek Tarczynski
@henk: could you explain the range check optimization that happens / doesn't happen in the case of jagged/rectangular arrays in more detail? i always thought that the speedup is due to the built-in IL instructions for one dimensional arrays...
stmax