多维数组与一维数组

这基本上是对这个问题的重述: Java:多维数组与一维数,但对于C#。

我有一定数量的元素可以作为网格存储。 我应该使用数组[x * y]还是数组[x] [y]?

编辑:哦,所以有一维数组[x * y],多维数组[x,y]和锯齿状数组[x] [y],我可能想要锯齿状?

C#在使用锯齿状数组 ( array[][] )方面有许多优点。 它们实际上通常会胜过多维数组。

话虽这么说,我个人会使用多维或锯齿状数组而不是单维数组,因为这会更紧密地匹配问题空间。 使用一维数组会增加实现的复杂性,但这并不能提供真正的好处,特别是与2D数组相比,内部时,它仍然只是一块内存。

我对不合理的大型arrays进行了测试,并惊讶地发现Jagged数组([y] [x])看起来比手动乘法[y * ySize + x]的单维数组更快。 并且多维数组[,]速度较慢但不是那么多。

当然你必须测试你的特定arrays,但看起来差异并不大,所以你应该只使用适合你所做的最好的方法。

 0.280 (100.0% | 0.0%) 'Jagged array 5,059x5,059 - 25,593,481' | 0.006 (2.1% | 2.1%) 'Allocate' | 0.274 (97.9% | 97.9%) 'Access' 0.336 (100.0% | 0.0%) 'TwoDim array 5,059x5,059 - 25,593,481' | 0.000 (0.0% | 0.0%) 'Allocate' | 0.336 (99.9% | 99.9%) 'Access' 0.286 (100.0% | 0.0%) 'SingleDim array 5,059x5,059 - 25,593,481' | 0.000 (0.1% | 0.1%) 'Allocate' | 0.286 (99.9% | 99.9%) 'Access' 0.552 (100.0% | 0.0%) 'Jagged array 7,155x7,155 - 51,194,025' | 0.009 (1.6% | 1.6%) 'Allocate' | 0.543 (98.4% | 98.4%) 'Access' 0.676 (100.0% | 0.0%) 'TwoDim array 7,155x7,155 - 51,194,025' | 0.000 (0.0% | 0.0%) 'Allocate' | 0.676 (100.0% | 100.0%) 'Access' 0.571 (100.0% | 0.0%) 'SingleDim array 7,155x7,155 - 51,194,025' | 0.000 (0.1% | 0.1%) 'Allocate' | 0.571 (99.9% | 99.9%) 'Access' for (int i = 6400000; i < 100000000; i *= 2) { int size = (int)Math.Sqrt(i); int totalSize = size * size; GC.Collect(); ProfileTimer.Push(string.Format("Jagged array {0:N0}x{0:N0} - {1:N0}", size, totalSize)); ProfileTimer.Push("Allocate"); double[][] Jagged = new double[size][]; for (int x = 0; x < size; x++) { Jagged[x] = new double[size]; } ProfileTimer.PopPush("Allocate", "Access"); double total = 0; for (int trials = 0; trials < 10; trials++) { for (int y = 0; y < size; y++) { for (int x = 0; x < size; x++) { total += Jagged[y][x]; } } } ProfileTimer.Pop("Access"); ProfileTimer.Pop("Jagged array"); GC.Collect(); ProfileTimer.Push(string.Format("TwoDim array {0:N0}x{0:N0} - {1:N0}", size, totalSize)); ProfileTimer.Push("Allocate"); double[,] TwoDim = new double[size,size]; ProfileTimer.PopPush("Allocate", "Access"); total = 0; for (int trials = 0; trials < 10; trials++) { for (int y = 0; y < size; y++) { for (int x = 0; x < size; x++) { total += TwoDim[y, x]; } } } ProfileTimer.Pop("Access"); ProfileTimer.Pop("TwoDim array"); GC.Collect(); ProfileTimer.Push(string.Format("SingleDim array {0:N0}x{0:N0} - {1:N0}", size, totalSize)); ProfileTimer.Push("Allocate"); double[] Single = new double[size * size]; ProfileTimer.PopPush("Allocate", "Access"); total = 0; for (int trials = 0; trials < 10; trials++) { for (int y = 0; y < size; y++) { int yOffset = y * size; for (int x = 0; x < size; x++) { total += Single[yOffset + x]; } } } ProfileTimer.Pop("Access"); ProfileTimer.Pop("SingleDim array"); } 

array[x,y]优点:
运行时将为您执行更多检查 。 将检查每个索引访问是否在允许的范围内。 使用另一种方法,您可以像a[y*numOfColumns + x]一样轻松地执行smth,其中x可以超过“列数”,并且此代码将提取一些错误的值而不会抛出exception。
更清晰的索引访问a[x,y]a[y*numOfColumns + x]更清晰

array[x*y]优点array[x*y]
更轻松地迭代整个arrays 。 您只需要一个循环而不是两个循环。

赢家是……我更喜欢array[x,y]