[ACCEPTED]-Efficient System.arraycopy on multidimensional arrays-arrays

Accepted answer
Score: 26

It's not difficult to use System.arraycopy 6 to do a quick deep copy. Here's an example 5 for a 2D array:

for (int i = 0; i < src.length; i++) {
    System.arraycopy(src[i], 0, dest[i], 0, src[0].length);
}

From a quick timing test, using 4 this to copy a 1000x1000 2D array 100 times 3 takes 40 milliseconds, versus 1740 milliseconds 2 using the more obvious two for loops and 1 assignment.

Score: 8

Like all performance timing questions, you 32 really need to benchmark in the environment 31 where you are expecting to run your code. Different 30 JVM versions and hardware (CPU, memory, etc) configurations 29 may have different results. It really depends 28 on your specific performance requirements.

But 27 then, before getting to this level of performance 26 tuning, you should first write the code 25 clearly and make it right first. The compiler 24 and JIT will be able to to a lot of optimizations 23 for you with normal algorithm expressions 22 but sometimes hand optimizations can confuse 21 these automated optimizations. After you 20 have a working product and if performance 19 is not then what you would like, then profile 18 and work on the hot spots only. (Though 17 sometimes for more complex code you may 16 need to refactor and/or change your logic.)

In 15 this case, if you copying entire arrays 14 then use System.arraycopy as this is the standard way to 13 do that. The compiler may now or in the 12 future provide additional optimizations 11 for that since the core APIs rely on this 10 heavily you can rest assured that this is 9 something that the JVM developers always 8 want to have running optimally.

You will 7 need to run through some loops though since 6 System.arraycopy can only do a single array object and with 5 Java multi-dimension arrays are really arrays 4 of arrays. So...

public int[][][] copyOf3Dim(int[][][] array) {
    int[][][] copy;
    copy = new int[array.length][][];
    for (int i = 0; i < array.length; i++) {
        copy[i] = new int[array[i].length][];
        for (int j = 0; j < array[i].length; j++) {
            copy[i][j] = new int[array[i][j].length];
            System.arraycopy(array[i][j], 0, copy[i][j], 0, 
                array[i][j].length);
        }
    }
    return copy;
}    

Or you could use Arrays.copyOf which 3 uses System.arraycopy and some reflection internally (so 2 is not as fast as directly using System.arraycopy yourself), but 1 does not do a deep copy.

Score: 4

System.arrayCopy is likely the fastest way to copy an array, but 3 it does not make deep copies.

It also cannot 2 do the more complex example in your second 1 question.

Score: 2

AFAIK, System.arrayCopy is the most efficient 4 and best way to copy your arrays. I am not 3 aware of any situations where the alternate 2 way of implementing your own loops would 1 be much more efficient for direct copies.

Score: 1

In my use case this

public <T> T[][] arrayCopy(T[][] array) {

    return Arrays.stream(array).
              map(el -> el.clone()).toArray(a -> array.clone());
}

was way faster than using 3 System.arraycopy or the straight forward two for loops solution.
Also 2 tested with primitives ( arrayCopy(int[][] array) ) and got the 1 same result.

More Related questions