Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Array[a,b,c] vs. Array[a][b][c]?

Tags:

arrays

c#

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?

like image 270
sooprise Avatar asked Dec 10 '22 17:12

sooprise


2 Answers

  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.

like image 88
Greg D Avatar answered Dec 24 '22 12:12

Greg D


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).

like image 29
stmax Avatar answered Dec 24 '22 12:12

stmax