为什么在x64 Java中比int慢很多?

问题描述 投票:90回答:8

我在Surface Pro 2平板电脑上运行带有Java 7更新45 x64(未安装32位Java)的Windows 8.1 x64。

下面的代码在i的类型为long时需要1688毫秒,在i是int的情况下需要109毫秒。为什么长(64位类型)比具有64位JVM的64位平台上的int慢一个数量级?

我唯一的猜测是,与64位整数相比,CPU要花费更多的时间来添加32位整数,但这似乎不太可能。我怀疑Haswell不会使用脉动加法器。

我正在Eclipse Kepler SR1中运行它,]。>

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;
    }

}

编辑:这是由VS 2013(以下),同一系统编译的等效C ++代码的结果。 long:72265ms int:74656ms

这些结果是在调试32位模式下进行的。

在64位释放模式下:long:875ms

long long:906ms int:1047ms

这表明我观察到的结果是JVM优化怪异而不是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;



}

编辑:刚刚在Java 8 RTM中再次尝试了此操作,没有明显变化。

我正在Surface Pro 2平板电脑上运行带有Java 7更新45 x64(未安装32位Java)的Windows 8.1 x64。当i的类型为long时,下面的代码花费1688ms,而当i的类型为int时,下面的代码花费109ms。为什么是...

java performance 32bit-64bit long-integer
8个回答
79
投票

当您使用long s时,我的JVM对内部循环执行了这一非常简单的操作:


22
投票

JVM堆栈是根据words


8
投票

Java虚拟机中数据的基本单位是单词。选择正确的字长取决于JVM的实现。 JVM实现应选择最小字长为32位。它可以选择较高的字长以提高效率。也没有任何限制,即64位JVM仅应选择64位字。


4
投票

我刚刚使用caliper编写了一个基准。


1
投票

为了记录,此版本进行了粗略的“热身”:


1
投票

用于记录:


0
投票

我没有要测试的64位计算机,但相差很大,这表明工作的字节码比更长的要多。


0
投票

我具有相同的差值,int 47ms,长750ms。看来问题仅以递减的方式出现。如果将--i更改为i = i-10,则int和long的基准测试结果相同。

© www.soinside.com 2019 - 2024. All rights reserved.