Tableau multidimensionnel contre unidimensionnel

Ceci est fondamentalement une reformulation de cette question: Java: tableau multidimensionnel vs unidimensionnel mais pour C #.

J’ai un certain nombre d’éléments qu’il est logique de stocker sous forme de grid. Devrais-je utiliser un tableau [x * y] ou un tableau [x] [y]?

EDIT: Oh, donc il y a un tableau à une dimension [x * y], un tableau multidimensionnel [x, y] et un tableau en escalier [x] [y], et je veux probablement en escalier?

L’utilisation de tableaux déchiquetés présente de nombreux avantages en C # ( array[][] ). En réalité, ils surperforment souvent les tableaux multidimensionnels.

Cela étant dit, j’utiliserais personnellement un tableau multidimensionnel ou dentelé au lieu d’un tableau à une dimension, car cela correspond plus étroitement à l’espace du problème. L’utilisation d’un tableau unidimensionnel ajoute une complexité à votre implémentation qui n’apporte pas de réels avantages, notamment par rapport à un tableau 2D, car en interne, il s’agit toujours d’un seul bloc de mémoire.

J’ai effectué un test sur des tableaux déraisonnablement grands et j’ai été surpris de constater que les tableaux Jagged ([y] [x]) semblent être plus rapides que le tableau à une seule dimension avec multiplication manuelle [y * ySize + x]. Et les tableaux multi-dimensionnels [,] sont plus lents mais pas beaucoup.

Bien sûr, vous devrez tester vos tableaux, mais il semblerait que la différence n’est pas si importante, vous devez donc utiliser l’approche qui vous convient le mieux.

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

Avantages du array[x,y] :
Runtime effectuera plus de contrôles pour vous . Chaque access à l’index sera vérifié pour être dans la plage autorisée. Avec une autre approche, vous pourriez facilement faire comme a[y*numOfColumns + x] où x peut être supérieur à “number of columns” et ce code extraira une valeur erronée sans générer d’exception.
Accès plus clair à l’index . a[x,y] est plus propre qu’un a[y*numOfColumns + x]

Avantages du array[x*y] :
Itération plus facile sur tout le tableau . Vous n’avez besoin que d’une boucle au lieu de deux.

Et le gagnant est … Je préférerais le array[x,y]