Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 ~50ms for Arrays.copyOf and ~160 ms for clone. Clone is a special native method for making copies, why is it so slow?

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

like image 979
Evgeniy Dorofeev Avatar asked Feb 06 '13 18:02

Evgeniy Dorofeev


1 Answers

I ran your code on my system: there's virtually no difference between them. Both clock in at about 30 milliseconds. My test is on OpenJDK 7.

To confirm I also ran it through Caliper, and used a larger array to emphasize the actual copying 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

Per request, here it is with array size 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 =============================
like image 160
Marko Topolnik Avatar answered Oct 21 '22 03:10

Marko Topolnik