开发者

What's the most efficient way to copy elements of a C# multidimensional array?

开发者 https://www.devze.com 2023-02-25 04:33 出处:网络
What\'s the most efficient way to nest my loops when copying from one multidimensional array to another in C#? The upper and lower bounds of each array are different, so I don\'t think Array.Copy() wi

What's the most efficient way to nest my loops when copying from one multidimensional array to another in C#? The upper and lower bounds of each array are different, so I don't think Array.Copy() will do the job for me. I currently have the following:

for (int x = lower.X; x <= upper.X; x++)
{
    for (int y = lower.Y; y <= upper.Y; y++)
    {
        for (int z = lower.Z; z <= upper.Z; z++)
        {
            copy[x, y, z] = Elements[x, y, z];
        }
    }
}

This is a relati开发者_运维百科vely low-level optimization, so will the compiler take care of this for me? Is there a better way to copy elements of a multidimensional array when the destination has different upper and lower bounds?


Array.Copy will work for you, but only to replace the innermost loop. You will have to calculate the source and destination indicies yourself, but that is certainly doable. The documentation for Array.Copy(Array, Int32, Array, Int32, Int32) explains how to do the math on indices so you can specify the source and target locations.

I highly recommend using Array.Copy everywhere it makes sense to use it, because it is crazy-fast. They do some serious assembler-foo to make it work well.

UPDATE

I am not sure how close this is to correct, because I haven't tried it, but this is something like how I think it might go:

int xLength = upper.X - lower.X + 1;
int yLength = upper.Y - lower.Y + 1;
int zLength = upper.Z - lower.Z + 1;

Array copy = Array.CreateInstance(Elements.GetType(), new { xLength, yLength, zLength }, new {lower.X, lower.Y, lower.Z});

int skippedX = lower.X - Elements.GetLowerBound(0);
int skippedY = lower.Y - Elements.GetLowerBound(1);
int skippedZ = lower.Z - Elements.GetLowerBound(2);

int sourceDim0Size = Elements.GetLength(1) * Elements.GetLength(2);
int sourceDim1Size = Elements.GetLength(2);

for (int x = 0; x < xLength; x++)
{
     for (int y = 0; y < yLength; y++)
     {
         int destinationIndex = x * yLength * zLength + y * zLength;
         int sourceIndex = (x + skippedX) * sourceDim0Size 
                           + (y + skippedY) * sourceDim1Size
                           + skippedZ;
         Array.Copy(Elements, sourceIndex, copy, 0, zLength);
     }
} 


Use Buffer.BlockCopy(). If it won't work in one step, copy first multidimensional array into single dimension array and then copy this single dimensional array to second multidimensional array.

References:

  • http://www.dotnetperls.com/buffer-blockcopy
  • http://msdn.microsoft.com/en-us/library/system.buffer.blockcopy.aspx


My guess is this can't get any simpler. It seems like you are doing a 3 dimensional pixel copy from one surface to another - short of hardware acceleration, I think it has to go one by one.

Well, if you have multiple cores, it might be faster to go a thread per core.

Maybe someone who know more for certin will chime in...

As a footnote, I'm curious if your example is a case where non-managed code would significantly outperform...

0

精彩评论

暂无评论...
验证码 换一张
取 消