What are the differences between multidimensional arrays double[,]
and array-of-arrays double[][]
in C#?
If there is a difference, what is the best use for each one?
What are the differences between multidimensional arrays 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 write some simple code using jagged and multidimensional arrays and then inspect the compiled assembly with an IL disassembler you will see that the storage and retrieval from jagged (or single dimensional) arrays are simple IL instructions while the 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 A multidimensional array is laid out linearly in memory, the actual value is found by multiplying together the indexes. However, given the array The Indexing the multidimensional array is faster. e.g. given the multidimensional array in this example A multidimensional array therefore allocates a continuous memory block, while a jagged array does not have to be square, e.g. PerformancePerformance 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:
|
|||||||||||||||||||||
|
Simply put multidimensional arrays are similar to a table in DBMS. So, if you are sure that the structure of data looks like a table (fixed rows/columns), you can use a multi-dimensional array. Jagged array are fixed elements & each element can hold an array of variable length E.g. Psuedocode:
Think of the above as a 2x2 table:
Think of the above as each row having variable number of columns:
|
|||||
|
Preface: This comment is intended to address the answer provided by Dmitry, but because of SO's silly reputation system, I can not post it where it belongs. Your assertion that one is slower than the other because of the method calls isn't correct. One is slower than the other because of more complicated bounds-checking algorithms. You can easily verify this by looking, not at the IL, but at the compiled assembly. For example, on my 4.5 install, accessing an element (via pointer in edx) stored in a two-dimensional array pointed to by ecx with indexes stored in eax and edx looks like so:
Here, you can see that there's no overhead from method calls. The bounds checking is just very convoluted thanks to the possibility of non-zero indexes, which is a functionality not on offer with jagged arrays. If we remove the sub,cmp,and jmps for the non-zero cases, the code pretty much resolves to Another complication is that there are plenty of cases where a modern compiler will optimize away the nested bounds-checking for element access while iterating over a single-dimension array. The result is code that basically just advances an index pointer over the contiguous memory of the array. Naive iteration over multi-dimensional arrays generally involves an extra layer of nested logic, so a compiler is less likely to optimize the operation. So, even though the bounds-checking overhead of accessing a single element amortizes out to constant runtime with respect to array dimensions and sizes, a simple test-case to measure the difference may take many times longer to execute. |
||||
|
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! |
|||
|
This might have been mentioned in the above answers but not explicitly: with jagged array you can use |
|||
|
double[,]
is a rectangular array, whiledouble[][]
is known as a "jagged array". The first will have the same number of "columns" for each row, while the second will (potentially) have a different number of "columns" for each row. – Great.And.Powerful.Oz Aug 19 '16 at 15:52