在C#中创建3D数组时,这是创建它的更好方法吗?
数组[a,b,c]或数组[a] [b] [c]?
或者只是偏好?
答案 0 :(得分:7)
这是两种根本不同的结构。如果一个人比另一个人更适合你的要求,那么当然更喜欢它。
数组[a,b,c]是一个三维矩形数组。这意味着所有元素都存在,但根据您的需要,可能会稀疏填充。数组[a] [b] [c]是三维锯齿状数组,或数组数组数组。
在所有条件相同的情况下,我相信我曾经读过一个源(我当时认为是权威的),锯齿状阵列通常比矩形阵列更好。我不记得原因是某种与性能相关的原因(缓存?)还是其他原因。
答案 1 :(得分:6)
矩形数组更容易初始化,但锯齿状数组更快。锯齿状数组更快的原因是因为存在直接支持一维数组的中间语言指令。比较以下两个反汇编:
c#方法:
public static int A()
{
int[,] a = new int[5, 5];
return a[3, 4];
}
汇编为:
.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
}
和c#方法:
public static int B()
{
int[][] a = null;
return a[3][4];
}
汇编为:
.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
}
如您所见,第一种方法使用(慢)方法调用来获取数组项的值:
call instance int32 int32[0...,0...]::Get(int32, int32)
而第二个使用(快得多)ldelem IL指令:
L_0004: ldelem.ref
L_0005: ldc.i4.4
L_0006: ldelem.i4
这是在发布模式下使用VS2008编译的。基准测试显示,锯齿状阵列版本比矩形阵列版本快25%(使用顺序索引和随机索引访问)。
答案 2 :(得分:1)
锯齿状数组(Array[a][b][c]
)快一点。虽然需要更多的代码来创建。
答案 3 :(得分:0)
如果你想要'矩形'数组,那么数组[a,b,c]应该更快 如果你需要其他形状,那么你应该使用Array [a] [b] [c] - 在这种情况下,第一行可以包含例如5个对象,第二个6个对象,等等。