Sprudelt Java JIT beim Ausführen von JDK-Code?

Ich war benchmarking-code, und ich konnte es nicht so schnell laufen wie mit java.math.BigIntegerauch wenn mit der exakt gleichen Algorithmus.
Also kopierte ich java.math.BigInteger Quelle in meinem eigenen Paket und versuchte dies:

//import java.math.BigInteger;

public class MultiplyTest {
    public static void main(String[] args) {
        Random r = new Random(1);
        long tm = 0, count = 0,result=0;
        for (int i = 0; i < 400000; i++) {
            int s1 = 400, s2 = 400;
            BigInteger a = new BigInteger(s1 * 8, r), b = new BigInteger(s2 * 8, r);
            long tm1 = System.nanoTime();
            BigInteger c = a.multiply(b);
            if (i > 100000) {
                tm += System.nanoTime() - tm1;
                count++;
            }
            result+=c.bitLength();
        }
        System.out.println((tm / count) + "nsec/mul");
        System.out.println(result); 
    }
}

Wenn ich diese ausführe (jdk 1.8.0_144-b01 auf MacOS) - Ausgänge:

12089nsec/mul
2559044166

Wenn ich es mit der import-Zeile auskommentiert:

4098nsec/mul
2559044166

Es ist fast drei mal so schnell wenn man die JDK version von BigInteger gegen meine version, auch wenn es mit dem genau gleichen code.

Habe ich untersucht den bytecode mit javap und den Vergleich von compiler-Ausgabe bei der Ausführung mit Optionen:

-Xbatch -XX:-TieredCompilation -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions 
-XX:+PrintInlining -XX:CICompilerCount=1

und beide Versionen scheinen generieren den gleichen code.
So ist hotspot mit einigen vordefinierten Optimierungen, die ich nicht verwenden kann, in meinem code? Ich habe immer verstanden, dass Sie nicht.
Wie erklärt sich dieser Unterschied?

InformationsquelleAutor der Frage Koen Hendrikx | 2017-08-28

Schreibe einen Kommentar