Ich verwende Windows 8.1 x64 mit Java 7 Update 45 x64 (kein 32-Bit-Java installiert) auf einem Surface Pro 2-Tablet.
Der folgende Code benötigt 1688 ms, wenn der Typ von i lang ist, und 109 ms, wenn i ein int ist. Warum ist long (ein 64-Bit-Typ) auf einer 64-Bit-Plattform mit einer 64-Bit-JVM um eine Größenordnung langsamer als int?
Meine einzige Spekulation ist, dass die CPU länger braucht, um eine 64-Bit-Ganzzahl als eine 32-Bit-Ganzzahl hinzuzufügen, aber das scheint unwahrscheinlich. Ich vermute, Haswell verwendet keine Ripple-Carry-Addierer.
Ich führe dies übrigens in Eclipse Kepler SR1 aus.
public class Main {
private static long i = Integer.MAX_VALUE;
public static void main(String[] args) {
System.out.println("Starting the loop");
long startTime = System.currentTimeMillis();
while(!decrementAndCheck()){
}
long endTime = System.currentTimeMillis();
System.out.println("Finished the loop in " + (endTime - startTime) + "ms");
}
private static boolean decrementAndCheck() {
return --i < 0;
}
}
Bearbeiten: Hier sind die Ergebnisse von äquivalentem C ++ - Code, der von VS 2013 (unten), demselben System, kompiliert wurde. lang: 72265 ms int: 74656 ms Diese Ergebnisse befanden sich im 32-Bit-Debug-Modus.
Im 64-Bit-Freigabemodus: lang: 875 ms lang lang: 906 ms int: 1047 ms
Dies deutet darauf hin, dass das Ergebnis, das ich beobachtet habe, eher eine Verrücktheit der JVM-Optimierung als CPU-Einschränkungen ist.
#include "stdafx.h"
#include "iostream"
#include "windows.h"
#include "limits.h"
long long i = INT_MAX;
using namespace std;
boolean decrementAndCheck() {
return --i < 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
cout << "Starting the loop" << endl;
unsigned long startTime = GetTickCount64();
while (!decrementAndCheck()){
}
unsigned long endTime = GetTickCount64();
cout << "Finished the loop in " << (endTime - startTime) << "ms" << endl;
}
Bearbeiten: Ich habe es gerade noch einmal in Java 8 RTM versucht, keine wesentliche Änderung.
long
als Schleifenzähler verwenden, da der JIT-Compiler die Schleife optimiert hat, als ich eine verwendet habe int
. Man müsste sich die Demontage des generierten Maschinencodes ansehen.
currentTimeMillis()
Ausführen, Ausführen von Code, der trivial vollständig optimiert werden kann usw. stinkt nach unzuverlässigen Ergebnissen.