Lew said:
For tests like this, would it make sense to run the loop a bunch of times
before measuring the speed in order to let the Hotspot mechanism settle
down?
It normally would be /much/ better, but in this specific case I don't think it
makes a lot of difference. One reason is that each loop of the test is quite
long (longer than I would normally use myself); the other is that both clone()
and arrayCopy() end up in precompiled (not JITed) code for the bulk of their
execution time, so there's not much for the JITer to do. It would probably
have made a more significant difference if we were including hand-written loop
in the benchmark (as in "mie"'s code).
Still, and for what it's worth, I wrapped a loop around the test. Code follow
at the end.
With SIZE = 10,000 and LOOPS = 100,000, I didn't find a lot of difference
beween copy() and new()+arrayCopy() using a 1.5 or 1.6, client or server, JVM
(there were small differences but not enough to be worth discussing). On the
other hand, with a much smaller array, such as "mei" used, SIZE = 10 and LOOPS
= 10,000,000, there were very considerable differences, with clone() typically
about 3 or 4 times slower (depending on which JVM I used). But then, the time
taken to copy a small array is much less likely to have a significant effect on
the overal runtime of a program.
I suspect there may be a test somewhere in the implementation of clone() which
switches to a faster implementation for arrays over a certain size.
Incidentally, one consistent feature of the numbers is that the 1.5 JVM was a
bit faster than the 1.6 for this benchmark...
-- chris
================================
public class Test
{
private final static int SIZE = 10 * 1000;
private final static int LOOPS = 100 * 1000;
public static void
main(String[] args)
{
System.out.println("Clone()\t\tNew()+ArrayCopy()");
int[] a = new int[SIZE];
for (;
timeIt(a);
}
private static void
timeIt(int[] a)
{
long start = System.currentTimeMillis();
for(int i = 0; i < LOOPS; i++)
{
int[] b = (int[])a.clone();
}
long end = System.currentTimeMillis();
System.out.print((end-start) + "\t\t");
start = System.currentTimeMillis();
for(int i = 0; i < LOOPS; i++)
{
int[] b = new int[a.length];
System.arraycopy(a, 0, b, 0, a.length);
}
end = System.currentTimeMillis();
System.out.println((end-start));
}
}
================================