Estou executando o Windows 8.1 x64 com Java 7 atualização 45 x64 (sem Java de 32 bits instalado) em um tablet Surface Pro 2.
O código a seguir leva 1688ms quando o tipo de i é longo e 109ms quando i é um int. Por que long (um tipo de 64 bits) é uma ordem de magnitude mais lento do que int em uma plataforma de 64 bits com uma JVM de 64 bits?
Minha única especulação é que a CPU demora mais para adicionar um inteiro de 64 bits do que um de 32 bits, mas isso parece improvável. Suspeito que Haswell não usa somadores de propagação de ondulação.
Estou executando isso no Eclipse Kepler SR1, btw.
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;
}
}
Editar: Aqui estão os resultados do código C ++ equivalente compilado pelo VS 2013 (abaixo), mesmo sistema. long: 72265ms int: 74656ms Esses resultados estavam no modo de depuração de 32 bits.
No modo de liberação de 64 bits: long: 875ms long long: 906ms int: 1047ms
Isso sugere que o resultado que observei é a estranheza da otimização da JVM, e não as limitações da CPU.
#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;
}
Edit: Apenas tentei isso novamente em Java 8 RTM, nenhuma mudança significativa.
currentTimeMillis()
, executar código que pode ser totalmente otimizado de maneira trivial, etc., cheira a resultados não confiáveis.