What are the differences between multidimensional arrays and array-of-arrays in C#? If there is a difference, what is the best use for each one?
Array of arrays (jagged arrays) are faster than multi-dimensional arrays and can be used more effectively. Multidimensional arrays have nicer syntax. If you will write some simple code using jagged arrays and multidimensional ones and then will inspect compiled assembly with IL disassembler you will see that storage and retrieval from jagged (or single dimensional) arrays are simple IL instructions while same operations for multidimensional arrays are method invocations which are always slower. Consider the following methods:
Their IL will be the following:
When using jagged arrays you can easily perform such operations as row swap and row resize. Maybe in some cases usage of multidimensional arrays will be more safe, but even Microsoft FxCop tells that jagged arrays should be used instead of multidimensional when you use it to analyse your projects. |
|||||||||||||||||
|
A multidimensional array creates a nice linear memory layout while a jagged array implies several extra levels of indirection. Looking up the value jagged[3][6] in a jagged array var jagged = new int[10][5] works like this: Look up the element at index 3 (which is an array) and look up the element at index 6 in that array (which is a value). For each dimension in this case, there's an additional look up (this is an expensive memory access pattern). A multidimensional array is laid out linearly in memory, the actual value is found by multiplying together the indexes. However, given the array var mult = new int[10,30] the Length property of that multidimensional array returns the total number of elements i.e. 10 * 30 = 300. The Rank property of a jagged array is always 1, but a multidimensional array can have any rank. The GetLength method of any array can be used to get the length of each dimension. For the multidimensional array in this example mult.GetLength(1) returns 30. Indexing the multidimensional array is faster e.g. given the multidimensional array in this example mult[1,7] = 30 * 1 + 7 = 37, get the element at that index 37. This is a better memory access pattern because only one memory location is involved, which is the base address of the array. A multidimensional array therefore allocates a continuous memory block, while a jagged array does not have to be square like. e.g. jagged[1].Length does not have to equal jagged[2].Length which would be true for any multidimensional array. PreformancePerformance wise, multidimensional arrays should be faster. A lot faster, but due to a really bad CLR implementation they are not.
The first row are timings of jagged arrays, the second shows multidimensional arrays and the third, well that's how it should be. The program is shown below, FYI this was tested running mono. (The windows timings are vastly different, mostly due to the CLR implementation variations). On windows, the timings of the jagged arrays are greatly superior, about the same as my own interpretation of what multidimensional array look up should be like, see 'Single()'. Sadly the windows JIT-compiler is really stupid, and this unfortunately makes these performance discussions difficult, there are too many inconsistencies. These are the timings I got on windows, same deal here, the first row are jagged arrays, second multidimensional and third my own implementation of multidimensional, note how much slower this is on windows compared to mono.
Source code:
|
|||||||||||||||||||
|
Multi-dimension arrays are (n-1)-dimension matrices. So Jagged arrays are just array of arrays - an array where each cell contains an array. So MDA are proportional, JD may be not! Each cell can contains an array of arbitrary length! |
|||
|