How to reshape an Array in c#

后端 未结 3 572
被撕碎了的回忆
被撕碎了的回忆 2020-12-06 02:19

I have a 3D array of bytes in c# which I have read from a bitmap:

byte[w, h, 3]

What is the easiest and more performance-friendly way of re

3条回答
  •  难免孤独
    2020-12-06 02:37

    This seems to work fine, because the array is already in the right shape in memory:

    var a = new byte[2,  2, 2] { { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } };
    var b = new byte[2 * 2, 2];
    
    //sizeof(byte) is obviously 1 here, but I put it there for documentation
    Buffer.BlockCopy(a, 0, b, 0, a.Length * sizeof(byte));
    

    For those interested: As for what to do if you really want to transpose a 2D array into 1D:

    byte[,] a = {
        {1, 2},
        {3, 4},
        {5, 6},
    };
    var b = new byte[a.GetLength(1) * a.GetLength(0)]; //Transpose
    
    const int R_STRIDE1 = 8; //Tune this for your CPU
    const int C_STRIDE1 = 8; //Tune this for your CPU
    
    //You should hoist the calls to GetLength() out of the loop unlike what I do here
    for (int r1 = 0; r1 < a.GetLength(0); r1 += R_STRIDE1)
    for (int c1 = 0; c1 < a.GetLength(1); c1 += C_STRIDE1)
        for (int r2 = 0; r2 < R_STRIDE1; r2++)
        for (int c2 = 0; c2 < C_STRIDE1; c2++)
        {
            var r = r1 + r2;
            var c = c1 + c2;
            if (r < a.GetLength(0) && c < a.GetLength(1))
                b[c * a.GetLength(0) + r] = a[r, c];
        }
    

    This should take advantage of caching in the CPU. I have only performed limited testing on this -- it could still be slow. Try tweaking it if it is.
    You can (somewhat non-trivially) extend this to a 3D array.

提交回复
热议问题