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.
longals 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.