0
\$\begingroup\$

I'm trying to build an extension method that will allow me to subdivide a huge array into much smaller ones. My current code is the following but it still takes about 2s to generate with an array of size 512x512x512 and the size of the sub cubes set to 32x32x32

public static T[][][][] Divide<T>(this T[][][] array, int xSize, int ySize, int zSize)
{
    int numberOfCubesInAxisX = array.Length / xSize;
    int numberOfCubesInAxisY = array[0].Length / ySize;
    int numberOfCubesInAxisZ = array[0][0].Length / zSize;
    T[][][][] arrayDivided = new T[numberOfCubesInAxisX * numberOfCubesInAxisY * numberOfCubesInAxisZ][][][];
    int index = 0;
    while (index < arrayDivided.Length)
    {
        int xIndex = index / numberOfCubesInAxisZ / numberOfCubesInAxisX;
        int yIndex = index / numberOfCubesInAxisZ % numberOfCubesInAxisY;
        int zIndex = index % numberOfCubesInAxisZ;
        arrayDivided[index] = new T[xSize][][];
        for (int x = 0; x < xSize; x++)
        {
            arrayDivided[index][x] = new T[ySize][];
            for (int y = 0; y < ySize; y++)
            {
                arrayDivided[index][x][y] = new T[zSize];
                for (int z = 0; z < zSize; z++)
                {
                    arrayDivided[index][x][y][z] = array[x + (xIndex * xSize)][y + (yIndex * ySize)][z + (zIndex * zSize)];
                }
            }
        }
        index++;
    }

    return arrayDivided;
}

If anyone have any clue on how to optimize it, i'll be glad to hear it! Thanks!

\$\endgroup\$
6
  • \$\begingroup\$ I have rolled back your latest edit. Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers. \$\endgroup\$ – Heslacher Mar 1 at 15:24
  • \$\begingroup\$ Jagged array is slow choice. I would like multi-dimentional one. [,,,] instead of [][][] for each cube. Additionally a pair of some math and Array.Copy calls will do the magic. Also Buffer.BlockCopy is the fastest for non-generic primitive-typed solution. Potentially you can speed up this by ~100 times. \$\endgroup\$ – aepot Mar 1 at 18:08
  • \$\begingroup\$ @aepot i have hard time knowing if jagged array are faster or not than multi-dimensional. Multiple link tell me otherwise (stackoverflow.com/questions/597720/…) and testing it on Unity (so with Mono) show me that jagged array are faster. Regarding Buffer.BlockCopy, i was currently looking into it and i think i can remove completly the z loop but the other one will be tough to delete... \$\endgroup\$ – Kamigaku Mar 1 at 18:34
  • \$\begingroup\$ For T you can't use Buffer.BlockCopy but can Array.Copy. First copies array segment only as bytes thus you must know the exact item size in bytes. Array.Copy will do it for T fluently, a bit slower but a payment for Generic method nature. \$\endgroup\$ – aepot Mar 1 at 18:37
  • \$\begingroup\$ About "slow" multi-dimentional array. Yes it can be slower to retreive an element while you iteration in one row but if yu want to copy a memory, the single-dimentional array will be rather faster as it provides solid memory area while. In other words if i want to copu 3xJagged, i go throug 2 loops. If I want to copy X-dimentional array, I call single Buffer.BlockCopy operation. For large data set single-dimentional array is best choice. Because calculating item address like x * ySize * zSize + y * zSize + z is always faster than go through 3 index-bound-checks. \$\endgroup\$ – aepot Mar 1 at 18:50
1
\$\begingroup\$

Just a quick shot regarding performance.....

The code is calculating

xIndex * xSize xSize*ySize*zSize times
yIndex * ySize xSize*ySize*zSize times
zIndex * zSize xSize*ySize*zSize times

while it only should be calculated once for each iteration of the while loop.

In addition, x only changes in the first for loop and y only changes in the second for loop.

\$\endgroup\$
1
  • \$\begingroup\$ Hi, thanks for the tip, i've indeed changed the code a little bit. The result is not an astronomical gain in time but it's a small good upgrade. Thanks for the tip. \$\endgroup\$ – Kamigaku Mar 1 at 15:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.