64位Java中使用long类型代替int类型会有益吗?

20
在64位的虚拟机中,相比于使用int(32位)来说,使用long(64位)是否会在性能上有所提升?在Java中,long的长度为64位,因此在64位系统中拉取和处理64位的字可能比拉取32位字更快。(我预计答案很可能是“不会”,但希望得到详细的解释。)
编辑:我的意思是,“在64位系统中拉取和处理64位的字可能比拉取32位字更快”,是因为我认为在64位系统中拉取32位数据需要先获取64位字,然后屏蔽掉前32位。

在某些处理器上,将32位的字读入64位寄存器比读取64位字要慢。但是现代大多数(全部?)处理器都不会出现这个问题。 - Hot Licks
3个回答

25

通常情况下,将long用于int可能会使您的速度变慢。

您首先需要关注的是64位CPU上的int是否需要额外的处理时间。在现代流水线CPU上这种情况高度不太可能发生。我们可以通过一个小程序轻松测试这一点。它所操作的数据应该足够小,以适合L1缓存,从而我们就可以测试这个特定的问题。在我的机器上(64位Intel Core2 Quad)基本没有区别。

在实际应用中,大多数数据无法驻留在CPU缓存中。我们必须担心从主内存到缓存的加载,这相对来说非常缓慢并且通常成为瓶颈。这样的加载按“缓存行”为单位工作,即64字节或更多,因此加载单个longint将花费相同的时间。

然而,使用long将浪费宝贵的缓存空间,因此缓存未命中会增加,这是非常昂贵的。Java的堆空间也会受到压力,因此GC活动会增加。

我们可以通过读取具有相同元素数量的巨大的long[]int[]数组来证明这一点。它们比缓存能够容纳的要大得多。在我的机器上,长整型版本需要更长时间,时间增加了65%。测试受到内存->缓存吞吐量的限制,并且long[]的内存占用量增加了100%。(为什么它不需要100%的时间我不知道; 显然还有其他因素起作用)


1
另一方面,在多处理器的多线程应用程序中,如果您在同一个8字节机器字中有两个4字节变量,并且它们经常被不同的线程/处理器访问,通常会看到显着的减速(大约10倍或更差),与将它们放在单独的机器字中相比。(当然,即使在单独的机器字中,如果它们在同一个缓存行中,效果也不是很好。) - Hot Licks
3
@irreputable,为什么使用 long 而不是 int 会浪费缓存空间? - Suraj Chandran
我的意思是,如果你使用 long 来表示 int,显然它会占用更多的空间。 - irreputable
使用 long 作为迭代变量会导致糟糕的代码(不是展开循环,可能更糟糕的分支预测等)。 - bestsss

5

我总是建议根据问题域选择正确的数据类型。

我的意思是,如果你需要64位长整型,则使用64位长整型,但如果你不需要64位长整型,则使用int。

在64位平台上使用32位并不昂贵,并且基于性能进行比较是没有意义的。

对我来说,下面的代码不太对:

for(long l = 0; l<100; l++)
 //SendToTheMoon(l);

SendToTheMoon 与此无关。


你的答案可能适用于企业应用程序,但假设我正在尝试对没有图形界面且高度性能导向的程序进行微观优化。拉取一百万个32位数据一百万次甚至比拉取64位数据慢一微秒。我真的想在这里找到答案而不是引发争论。:) - Suraj Chandran
1
@Suraj Chandran - 我的回答是 “原样”,我不相信你会因为你的问题或评论而看到性能上的变化。也许我错了,因此请测试一下。我总是遵循使用所需的原则,在这种情况下,如果我可以使用 int / short,那么为什么要使用 long? - JonH
3
虽然这是好建议,但它并没有回答被问出的问题。 - Jason Wheeler
@daniel,这不正确,我确定在32位系统上运行16位程序比32位程序慢。 - Suraj Chandran
@Bigwheels - 有时候问题没有明确的解决方案。 - JonH
显示剩余4条评论

1

可能会更快,也可能会更慢。这取决于具体的Java实现以及您如何使用这些变量。但总的来说,这可能不足以引起担忧。


3
部分实现内部使用64位堆栈,而有些则使用32位堆栈。变量大小会影响变量对齐方式,其中包括影响多任务执行的方式。这是一个涉及多个不同变量的方程式。 - Hot Licks
您能指向至少一个具有32位堆栈的64位实现吗?很难相信 :) - Suraj Chandran
1
对你问题的更直接的回答是:我相信第一个 Sun 的“64 位”JVM 有一个 32 位的堆栈。这是一个把几个 64 位调整编译到 32 位 JVM 中以利用 64 位寻址特性的折中方案。同样,IBM 生产了两个具有 32 位堆栈的“64 位”JVM。然而,可能是第一个“生产”64 位 JVM 的是 IBM iSeries JVM,因为它是从头开始构建为 64 位 JVM(而不是像 Sun 和其他 IBM JVM 系列一样从 32 位 JVM 扩展和 #ifdefed)。 - Hot Licks
所以我们回到了0,也就是说可能不会有任何“生产级别”的64位JVM与32位堆栈。 - Suraj Chandran
我不知道。32/64方案可能仍然很受欢迎,因为它比纯64方案更节省存储空间。 - Hot Licks
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接