Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
A DESCRIPTION OF THE REQUEST : When we copy one Java array to another, there are two possible ways: System.arraycopy method and the simple loop like this: for (int j = 0; j < a.length; j++) b[j] = a[j]; All Java tutorials recommend using System.arraycopy, when possible: it works faster and is written more shortly. Moreover, some professional IDEs, like IntelliJ IDEA, detect simple loops, like the loop above, and warn about a nonoptimal code. However, for very short array (a.length=1,2,3), the testing shows that the simple loop works essentially faster then System.arraycopy. Below is a simple test illustrating this: import java.util.Locale; public class ArraycopySpeed { public static void main(String[] args) { if (args.length < 3) { System.out.println("Usage: " + ArraycopySpeed.class.getName() + " maxArrayLength loopLength numberOfIterations"); return; } final int maxLen = Integer.parseInt(args[0]); final int n = Integer.parseInt(args[1]); int numberOfIterations = Integer.parseInt(args[2]); for (int iter = 1; iter <= numberOfIterations; iter++) { System.out.println("Test #" + iter); for (int len = 0; len < maxLen; len++) { int[] a = new int[len], b = new int[len]; long t1 = System.nanoTime(); for (int k = 0; k < n; k++) { for (int j = 0; j < a.length; j++) b[j] = a[j]; } long t2 = System.nanoTime(); for (int k = 0; k < n; k++) { System.arraycopy(a, 0, b, 0, a.length); } long t3 = System.nanoTime(); System.out.printf(Locale.US, "%d elements: %.3f ns simple loop, %.3f ns arraycopy %n", len, (double)(t2 - t1) / n, (double)(t3 - t2) / n); } System.out.println(); } } } On my computer (Intel Quad Core, Windows Vista-64, JVM 1.7.0-ea-b74, 64 bit) only for 5 or more elements System.arraycopy becomes the optimal solution. For Is it possible to improve this behavior and always translate short arraycopy calls into an optimal code? JUSTIFICATION : If we need to copy short Java arrays in inner loops and this code is critical for the application performance, we are enforced to create an ugly code like the following: if (a.length < 5) { for (int j = 0; j < a.length; j++) b[j] = a[j]; } else { System.arraycopy(a, 0, b, 0, a.length); } and there are no any guarantees that it will be the right choice for any JVMs. It can be really important, for example, if a Java array contains 2 or 3 coordinates in a plane or 3D space, and the algorithm copies one set of coordinates to another while processing millions of points. In my last module the Java array was used for storing a set of indexes in some multilevel histogram, and the number of indexes varies from 1 to 5-6. EXPECTED VERSUS ACTUAL BEHAVIOR : EXPECTED - System.arraycopy should always work faster than an equivalent Java loop. ACTUAL - For short arrays (several elements) Java loop sometimes works faster than System.arraycopy. ---------- BEGIN SOURCE ---------- import java.util.Locale; public class ArraycopySpeed { public static void main(String[] args) { if (args.length < 3) { System.out.println("Usage: " + ArraycopySpeed.class.getName() + " maxArrayLength loopLength numberOfIterations"); return; } final int maxLen = Integer.parseInt(args[0]); final int n = Integer.parseInt(args[1]); int numberOfIterations = Integer.parseInt(args[2]); for (int iter = 1; iter <= numberOfIterations; iter++) { System.out.println("Test #" + iter); for (int len = 0; len < maxLen; len++) { int[] a = new int[len], b = new int[len]; long t1 = System.nanoTime(); for (int k = 0; k < n; k++) { for (int j = 0; j < a.length; j++) b[j] = a[j]; } long t2 = System.nanoTime(); for (int k = 0; k < n; k++) { System.arraycopy(a, 0, b, 0, a.length); } long t3 = System.nanoTime(); System.out.printf(Locale.US, "%d elements: %.3f ns simple loop, %.3f ns arraycopy %n", len, (double)(t2 - t1) / n, (double)(t3 - t2) / n); } System.out.println(); } } } ---------- END SOURCE ---------- CUSTOMER SUBMITTED WORKAROUND : Manual choosing between System.arraycopy and simple Java loop for a case of short arrays.
|