rectangular arrays are easier to initialize, but notched 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 following two disassemblies:
C # method:
public static int A() { int[,] a = new int[5, 5]; return a[3, 4]; }
compiles:
.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 C # method:
public static int B() { int[][] a = null; return a[3][4]; }
compiles:
.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 element:
call instance int32 int32[0...,0...]::Get(int32, int32)
while the second uses (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 indexes).
stmax source share