http://www.dotnetperls.com/jagged-2d-array-memory
http://blog.mischel.com/2013/05/08/are-jagged-arrays-faster-than-rectangular-arrays/
The two-dimensional array will result in less work for the garbage collector, but can be slower when accessing elements.
A rectangular array consists of a single allocation of size rows * cols * element-size, plus about 50 bytes of overhead for array metadata. A jagged array requires somewhat more memory. It consists of an allocation of size rows * sizeof(IntPtr) (plus metadata), and there is a separate allocation for each row, of size cols * element-size.
Don’t immediately fall for the simplistic “jagged is faster” hype that’s all too often spouted as a matter of faith without understanding the wider implications.
The rectangular array is one big block of memory. The jagged array is one block of memory for an array of row references, and a separate block of memory for each row. Accessing an arbitrary element in a jagged array, then, requires two separate lookups in memory that can be scattered all over. The result is approximately twice as many cache misses for the jagged array when compared to the rectangular array.
It’s pretty clear here that traversing a jagged array sequentially is hugely faster than traversing an equivalent rectangular array. The primary reason, it turns out, is array bounds checking. When accessing array[i, j], the runtime has to check the bounds of both indexes. You would think that it would have to do the same thing for the jagged array, but the compiler optimizes the code to something akin to this:
private int SimpleSumJagged2(byte[][] array, int rows, int cols)
{
var SimpleSum = 0;
for (var i = 0; i < rows; ++i)
{
var theRow = array[i];
for (var j = 0; j < cols; ++j)
{
SimpleSum += theRow[j];
}
}
return SimpleSum;
}