1

I have two multi-dimentional arrays declared like this:

bool?[,] biggie = new bool?[500, 500];
bool?[,] small = new bool?[100, 100];

I want to copy part of the biggie one into the small. Let’s say I want from the index 100 to 199 horizontally and 100 to 199 vertically.

I have written a simple for statement that goes like this:

for(int x = 0; x < 100; x++)
{
    For(int y = 0; y < 100; y++)
    {
        Small[x,y] = biggie[x+100,y+100];
    }
}

I do this A LOT in my code, and this has proven to be a major performance jammer.

Array.Copy only copies single-dimentional arrays, and with multi-dimentional arrays it just considers as if the whole matrix is a single array, putting each row at the end of the other, which won’t allow me to cut a square in the middle of my array.

Is there a more efficient way to do this?

Ps.: I do consider refactoring my code in order not to do this at all, and doing whatever I want to do with the bigger array. Copying matrixes just can’t be painless, the point is that I have already stumbled upon this before, looked for an answer, and got none.

Marcelo
  • 3,371
  • 10
  • 45
  • 76

1 Answers1

0

In my experience, there are two ways to do this efficiently:

  • Use unsafe code and work directly with pointers.
  • Convert the 2D array to a 1D array and do the necessary arithmetic when you need to access it as a 2D array.

The first approach is ugly and it uses potentially invalid assumptions since 2D arrays are not guaranteed to be laid out contiguously in memory. The upshot to the first approach is that you don't have to change your code that is already using 2D arrays. The second approach is as efficient as the first approach, doesn't make invalid assumptions, but does require updating your code.

Eric
  • 6,364
  • 1
  • 32
  • 49
  • Would the second approach involve using Array.Copy and getting 100 to 199, 500 to 699 and so on? I was considering it.. As of pointers, I will check it out, I don't know a lot about it.. Thank you! – Marcelo Mar 29 '11 at 13:50
  • 1
    I think Eric rather meant creating 1D arrays, like int[] array = new int[width * height]; And accessing elements in it by doing simple arithmetic: array[y * width + x]; (for row-wise arrays) or array[x * height + y]; (for column-wise). 1D arrays are much faster then multiD in c#, you can read more about it fe. here: http://stackoverflow.com/questions/468832/why-are-multi-dimensional-arrays-in-net-slower-than-normal-arrays – Marcin Deptuła Mar 29 '11 at 13:54
  • @Ravadre, yes, that's what I meant. – Eric Mar 29 '11 at 14:12