Array multidimensional vs. unidimensional

Esto es básicamente una reafirmación de esta pregunta: Java: matriz multidimensional vs. unidimensional pero para C #.

Tengo una cantidad establecida de elementos que tienen sentido para almacenar como una cuadrícula. ¿Debo usar una matriz [x * y] o una matriz [x] [y]?

EDIT: Oh, entonces hay una matriz dimensional [x * y], matriz multidimensional [x, y] y matriz irregular [x] [y], y probablemente quiero irregular.

Hay muchas ventajas en C # al usar arreglos irregulares ( array[][] ). En realidad, a menudo superarán las matrices multidimensionales.

Dicho esto, yo personalmente usaría una matriz multidimensional o dentada en lugar de una matriz dimensional única, ya que esto se ajusta más al espacio del problema. El uso de una matriz unidimensional está agregando complejidad a su implementación que no proporciona beneficios reales, especialmente cuando se compara con una matriz 2D, ya que internamente, sigue siendo un solo bloque de memoria.

Realicé una prueba en matrices irrazonablemente grandes y me sorprendió ver que las matrices irregulares ([y] [x]) parecen ser más rápidas que la matriz de una sola dimensión con la multiplicación manual [y * ySize + x]. Y los arreglos multidimensionales [,] son ​​más lentos, pero no tanto.

Por supuesto, tendría que probar sus arreglos particulares, pero parecería que los diferentes no son muchos, por lo que debería usar el método que mejor se adapte a lo que está haciendo mejor.

 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"); } 

Pros de array[x,y] :
Runtime realizará más comprobaciones por ti . Cada acceso al índice se verificará dentro del rango permitido. Con otro enfoque, podría hacer fácilmente algo como a[y*numOfColumns + x] donde x puede ser más que “número de columnas” y este código extraerá algún valor incorrecto sin lanzar una excepción.
Acceso más claro al índice . a[x,y] es más limpio que a[y*numOfColumns + x]

Pros de array[x*y] :
Una iteración más fácil en toda la matriz . Solo necesitas un bucle en lugar de dos.

Y el ganador es … preferiría array[x,y]