Why is cloning arrays so slow?

This test

for (;;) { int[] a = new int[10]; System.gc(); long t0 = System.currentTimeMillis(); for (int i = 0; i < 1000000; i++) { // int[] b = a.clone(); int[] b = Arrays.copyOf(a, a.length); } System.out.println(System.currentTimeMillis() - t0); } 

shows ~ 50 ms for Arrays.copyOf and ~ 160 ms for clone. Clone is a special proprietary way to create copies, why is it so slow?

I tested the test on my HotSpot 1.7.0_11-b21 JVM client. Note that when the size of the array increases, the difference between the clone and copyOf disappears.

+7
source share
2 answers

I found a good article explaining why the clown here is slow http://www.javaspecialists.eu/archive/Issue124.html . In short, this is because int []. Clone simply uses Object.clone, and this method performs two checks before copying the array:

1. Check if the instance is a regular object or an array.

2. Check if the array has primitives or objects.

I added these checks to the Arrrays.copyOf test

  for (int i = 0; i < 1000000; i++) { Class cls = a.getClass(); if (cls.isArray() && !cls.getComponentType().isAssignableFrom(Object.class)) { int[] b = Arrays.copyOf(a, a.length); } } 

and the test showed no difference between the clone and Arrayys.copyOf. If it were a specialized version for cloning arrays, it would be fast.

0
source

I ran your code on my system: there is practically no difference between them. Both timers are approximately 30 milliseconds. My test is on OpenJDK 7.

To confirm that I also ran it through Caliper, and used a larger array to emphasize the actual copy performance:

 public class Performance extends SimpleBenchmark { final int[] source = new int[1000]; public int timeClone(int reps) { int sum = 0; for (int i = reps; i > 0; i--) sum += source.clone().length; return sum; } public int timeCopyOf(int reps) { int sum = 0; for (int i = reps; i > 0; i--) sum += Arrays.copyOf(source,source.length).length; return sum; } public static void main(String... args) { Runner.main(Performance.class, args); } } 

Result:

  0% Scenario{vm=java, trial=0, benchmark=Clone} 2141.70 ns; σ=5416.80 ns @ 10 trials 50% Scenario{vm=java, trial=0, benchmark=CopyOf} 2168.38 ns; σ=1545.85 ns @ 10 trials benchmark us linear runtime Clone 2.14 ============================= CopyOf 2.17 ============================== vm: java trial: 0 

Upon request, here it has an array size of 10:

  0% Scenario{vm=java, trial=0, benchmark=Clone} 30.07 ns; σ=2.12 ns @ 10 trials 50% Scenario{vm=java, trial=0, benchmark=CopyOf} 29.34 ns; σ=161.38 ns @ 10 trials benchmark ns linear runtime Clone 30.1 ============================== CopyOf 29.3 ============================= 
+5
source

All Articles