0

I know if I want to copy an array of the same type, I have at least 3 Options, I can use a double for loop, use Array.copy or Buffer.BulkCopy. The two copy methods are much faster. See for instance here: https://stackoverflow.com/a/33030421 .

Both copy methods allow you to only copy parts of the 2d array but Array.copy needs rank of source and destination to be equal while bulk.copy does not.

I get data from a com interface and doubles or int come through as object. Lets say I want to include a cast on the copy. I can do this:


Stopwatch watch = new Stopwatch();
const int width = 2;
const int depth = 10 * 1000000;
Random r = new Random(100);
object[,] objdata = new object[width, depth];
for (int i = 0; i < width; i++)
{
    for (int j = 0; j < depth; j++)
    {
        objdata[i, j] = r.Next();
    }
}


        int[,] arr2dint = new int[width, depth];
        watch.Reset();
        watch.Start();
        Array.Copy(objdata, 0, arr2dint, 0, objdata.GetLength(0) * objdata.GetLength(1));
        watch.Stop();
        Console.WriteLine("ArrayCopy to 2 dimensional array including cast took {0}", watch.ElapsedMilliseconds);
        watch.Reset();

        var bufferloopcast = new int[width, depth];
        watch.Start();
        for (int i = 0; i < width; i++)
        {
            for (int j = 0; j < depth; j++)
            {
                bufferloopcast[i, j] = (int)objdata[i, j];
            }
        }
        watch.Stop();
        Console.WriteLine("Loop-copy to 2 dimensional array including cast took {0} ms", watch.ElapsedMilliseconds);

Now the copy method is slower. Also it comes with the limitation that source and destination rank have to be equal so I cannot use it to copy only part of an array (say only the first row).

I cannot make the Buffer.BulkCopy to work, error must be primitive type. I tried this, in wain:

 int[,] buff2dint = new int[width, depth];
        watch.Reset();
        watch.Start();
        int sizeo = Marshal.SizeOf(objdata[0, 0]);
        Buffer.BlockCopy(objdata, 0, buff2dint, 0, objdata.GetLength(0) * objdata.GetLength(1)* sizeo);
        watch.Stop();
        Console.WriteLine("BufferCopy to 2 dimensional array including cast took {0}", watch.ElapsedMilliseconds);

SO, why did array.copy become so slow? And what is the best method to copy an 2d array, or parts of it, if you need to include a cast?

1
  • 1
    as a small side note, do you know you can use separators for int litterals? Seems more readable IMO : const int depth = 10_000_000; Commented Apr 28, 2020 at 15:56

1 Answer 1

1

What about using an array of arrays instead of a 2d-array?

int [][] buff2dint = new int[width][];
for(int i = 0; i < width; ++i)
{
   buff2dint[i] = new int[depth];
   Buffer.BlockCopy(srcArray, 0, buff2dint[i], depth);
}
Sign up to request clarification or add additional context in comments.

1 Comment

thanks but if the source is object[,] and the destination int[] this would still fail, no?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.