C# has support for multidimensional arrays, which are useful for representing elements in a 2D or 3D grid:
int[,] twoDimensions = new int[20, 20];
int[,,] threeDimensions = new int[20, 20, 20];
Under the covers, these arrays are allocated as a single-dimensional array:
// Your code
int[,] twoDimensions = new int[20, 20];
// Under the covers:
int[] actualArray = new int[20 * 20];
When accessing a multidimensional array, C# performs bounds checks on each dimension, then converts each separate access value (x, y, z, etc) into a single access value. Reference source.
T[] data = new T[];
int[] lengths = new int[3];
T Get(int x, int y, int z)
{
// Bounds checks
if (x < 0 || x >= lengths[0])
throw new OutOfRangeException(...);
if (y < 0 || y >= lengths[1])
throw new OutOfRangeException(...);
if (z < 0 || z >= lengths[2])
throw new OutOfRangeException(...);
// Convert 3D access to a 1D access
var access = x + y * lengths[0] + z * lengths[0] * lengths[1];
return data[access];
}
Converting to a single-dimensional array is straightforward and can reduce access speeds by 37-47% (see the the benchmarks below).
// 2D array example
int[,] twoDimensions = new int[20, 20];
int randomValue = twoDimensions[6, 6];
// 1D array example
int[] oneDimension = new int[20 * 20];
int randomValue = oneDimension[6 + 6 * 20];
Arrays with dimensions that are a power of 2 can be optimised further by replacing additions and multiplications with bitwise operators and bit-shifts:
int[] oneDimension = new int[32 * 32];
int randomValue = oneDimension[6 | (6 << 5)];
Here are the results of accessing 1,000,000 random items inside a 256x256x256 array:
For more information on the faster unsafe approach using unmanaged memory, check out this article.
Top comments (0)