Hello!
Here is
a video I've watched recently and I'd like to have a simple check that on java. I've chosen to iterate over array in forward and backward ways. The code is following.
public class ArrReading {
private static long tmp = 0;
private static int[] arr = new int[1000000];
static {
System.out.println("Initializes array...");
Random R = new Random(1);
for (int i = 0; i < arr.length; i++) {
arr[i] = R.nextInt();
}
}
public static void main(String[] args) {
ArrReading bb = new ArrReading();
System.out.println("Doing warm up");
bb.warmUp();
System.out.println("Doing experiment");
bb.runExperiment();
}
public void warmUp() {
final int[] ints = {1, 2, 3, 4, 5};
for (int i = 0; i < 10000; i++) {
decrementFor(ints);
incrementFor(ints);
}
}
public void runExperiment() {
long time2 = System.nanoTime();
tmp += decrementFor(arr);
long tD = System.nanoTime() - time2;
long time = System.nanoTime();
tmp += incrementFor(arr);
long tI = System.nanoTime() - time;
System.out.println("++ took: " + tI);
System.out.println("-- took: " + tD);
System.out.println("ratio [--/++]=" + (tD * 1.0 / tI));
}
public int decrementFor(int[] ar) {
int sum = 0;
for (int i = ar.length - 1; i >= 0; i--) {
sum += ar[i];
}
return sum;
}
public int incrementFor(int[] ar) {
int sum = 0;
for (int i = 0; i < ar.length; i++) {
sum += ar[i];
}
return sum;
}
}
I believe I've got correctly compiled method, no OSR. There is partial output from PrintCompilation:
278 23 java.util.concurrent.atomic.AtomicLong::compareAndSet (13 bytes)
282 1% own.my.incdec.ArrReading::<clinit> @ 30 (54 bytes)
Doing warm up
299 24 own.my.incdec.ArrReading::decrementFor (25 bytes)
300 25 own.my.incdec.ArrReading::incrementFor (24 bytes)
Doing experiment
++ took: 354000
-- took: 413000
ratio [--/++]=1.1666666666666667
I have compiled my class ArrReading by using
$ java -version
java version "1.6.0_29"
Java(TM) SE Runtime Environment (build 1.6.0_29-b11-402-11M3527)
Java HotSpot(TM) 64-Bit Server VM (build 20.4-b02-402, mixed mode)
and run it using java 1.6.0_29-b11-402-11M3527 and 1.7.0_40-b43. Results for different versions of java are different, but the interesting issue is that they are not concrete - they differ from run to run. I've calculated average and standard deviation:
jdk 1.6 jdk 1.7
mean 1.0048932375 1.1780869565
stdev 0.1039612282 0.0786770806
I must say that for both cases I've tried to gather GC log. For both cases GC hasn't been run even once. Eden has been full for about 20% only, there is no reason for it to be run. Another interesting fact is that HotSpot of jdk 1.7 seems to be more performant, cause it compiles these methods on 171st milliseconds as opposed to jdk 1.6 on 300th:
151 8 % ArrReading::<clinit> @ 30 (54 bytes)
Doing warm up
169 9 ArrReading::incrementFor (24 bytes)
171 10 ArrReading::decrementFor (25 bytes)
Do you have any explanation for such a behavior?
Why numbers differ from run to run? How can I debug what's going on there?
Thank you!