简体   繁体   中英

C# Array[a,b,c] vs. Array[a][b][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?

  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.

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

A jagged array ( Array[a][b][c] ) is a little faster. It takes a little more code to create though.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM