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.BigInteger
auch 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
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ja, die HotSpot-JVM ist eine Art von "Betrug", denn es hat eine spezielle version von einigen
BigInteger
Methoden, die Sie finden nicht in Java-code. Diese Methoden werden aufgerufen,JVM-Interna.Insbesondere
BigInteger.multiplyToLen
ist instrinsic-Methode HotSpot. Es ist eine Besondere hand-codiert Montage Durchführung in JVM-source-Basis, aber nur für x86-64-Architektur.Können Sie diese deaktivieren, instrinsic mit
-XX:-UseMultiplyToLenIntrinsic
option zu zwingen, die JVM zu verwenden, Reine Java-Implementierung. In diesem Fall ist die Leistung ähnlich sein wird, um die Leistung Ihrer kopierten code ein.P. S. Hier ist ein Liste der anderen HotSpot intrinsische Methoden.
InformationsquelleAutor der Antwort apangin
In Java 8 dies ist in der Tat eine intrinsische, eine leicht modifizierte version der Methode:
Läuft dieser mit:
Diese drucken viele Linien und einer von Ihnen wird sein:
In Java 9 auf der anderen Seite, die Methode scheint nicht zu sein, eine intrinsische mehr, aber im Gegenzug fordert er eine Methode, die eine intrinsische:
So läuft der gleiche code unter Java 9 (mit denselben Parametern) wird verraten:
Darunter ist es der gleiche code für die Methode - nur eine leicht andere Namensgebung.
InformationsquelleAutor der Antwort Eugene