C#数组[a,b,c]与数组[a] [b] [c]?

soo*_*ise 4 c# arrays

在C#中创建3D数组时,这是创建它的更好方法吗?

数组[a,b,c]或数组[a] [b] [c]?

或者只是一个偏好问题?

Gre*_*g D 7

  1. 这是两种根本不同的结构.如果一个人比另一个人更适合你的要求,那么当然更喜欢它.

    数组[a,b,c]是三维矩形阵列.这意味着所有元素都存在,但根据您的需要,可能会稀疏填充.数组[a] [b] [c]是三维锯齿状数组,或数组数组数组.

  2. 在所有条件相同的情况下,我相信我曾经读过一个源(我当时认为是权威的),锯齿形阵列通常比矩形阵列更好.我不记得原因是某种与性能相关的原因(缓存?)还是其他原因.


stm*_*max 6

矩形数组更容易初始化,但锯齿状数组更快.锯齿状数组更快的原因是因为存在直接支持一维数组的中间语言指令.比较以下两个反汇编:

c#方法:

public static int A()
{
    int[,] a = new int[5, 5];
    return a[3, 4];
}
Run Code Online (Sandbox Code Playgroud)

编译为:

.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 
}
Run Code Online (Sandbox Code Playgroud)

和c#方法:

public static int B()
{
    int[][] a = null;
    return a[3][4];
}
Run Code Online (Sandbox Code Playgroud)

编译为:

.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 
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,第一种方法使用(慢)方法调用来获取数组项的值:

call instance int32 int32[0...,0...]::Get(int32, int32)
Run Code Online (Sandbox Code Playgroud)

而第二个使用(快得多)ldelem IL指令:

L_0004: ldelem.ref 
L_0005: ldc.i4.4 
L_0006: ldelem.i4 
Run Code Online (Sandbox Code Playgroud)

这是在发布模式下使用VS2008编译的.基准测试表明,锯齿状阵列版本比矩形阵列版本快25%(使用顺序索引和随机索引访问).