int与long比较会影响Java的性能吗?
比较int和long是否会影响性能?i、 eint与long比较会影响Java的性能吗?,java,comparison,int,long-integer,Java,Comparison,Int,Long Integer,比较int和long是否会影响性能?i、 e int x = 1; long y = 2; if (x < y) doStuff(); intx=1; 长y=2; 如果(x
int x = 1;
long y = 2;
if (x < y) doStuff();
intx=1;
长y=2;
如果(x
与之相反:
int x = 1;
int y = 2;
if (x < y) ...
intx=1;
int y=2;
如果(x
有类型转换吗?还是内存中的位布局允许直接比较?(也就是说,对于int,long中的额外位都可以假定为0)Java语言规范说,出现了二进制数字提升,因此
int
被转换为long
。在实践中,转换非常简单——在大多数现代硬件上,这不是一个昂贵的操作。然而,整个问题不应该真正成为性能问题;使用long不是因为性能,而是因为需要能够管理较大的数值
与性能问题一样,真正的答案是:
a) 在性能成为问题之前,您不应该担心它
b) 在此阶段,您应该分析或进行测量,以查看效果。根据第5.6.2节,对数值比较运算符的操作数执行二进制数值提升。这意味着在比较之前,int
将被提升为long
当运算符将二进制数字提升应用于一对操作数(每个操作数必须表示可转换为数字类型的值)时,以下规则依次适用:
- 如果其中一个操作数的类型为double,则另一个操作数将转换为double
- 否则,如果其中一个操作数的类型为float,则另一个操作数将转换为float
- 否则,如果其中一个操作数的类型为long,则另一个操作数将转换为long
- 否则,两个操作数都将转换为int类型
- 乘法运算符*、/和%(§15.17)
- 数字类型+和-(§15.18.2)的加减运算符
- 数值比较运算符=(§15.20.1)
- 数值相等运算符==和!=(§15.21.1)
JLS是一个很好的参考资料,它明确了类型推广的要求,但没有人谈论本质问题 在机器级别(后JIT编译或深入JVM),具有64位ALU的处理器可能会执行64到32位比较,一条指令对32位操作数进行符号扩展,另一条指令执行64位范围的比较,然后执行
doStuff
调用的分支
对于int
到int
32位比较,可以省略符号扩展。因此,现代内核的区别在于一条指令或一个周期
如果机器有32位ALU,那么64位比较可能需要4条指令:比较、分支、测试、分支。但它可以在3(带借阅、转借、分支的转借)中使用正确的指令和/或一个额外的寄存器来完成
int
到int
需要两个:比较和分支。因此,差异是1或2个指令/周期
很少有一个或两个周期会产生有意义的性能差异的程序。使用您需要的类型,以确保您的程序能够在您可以想象的未来十年左右的所有意外情况下工作。忘掉这两个周期吧
注意:64位实际上会对性能造成有意义的影响,这会使数据结构(以及较小程度的代码)的大小增加2倍,从而使缓存和页面未命中变得更加频繁。但是你也不应该提前担心这一点
不幸的是,Java使得不可能对未绑定的类型进行别名。从
int
到long
或从float
到double
再到back的更改是非常重要的:在许多情况下,这是一个严重的语言缺陷。与什么相比,它会影响性能吗?与int vs int comparisoni相反,它是一个不断扩大的原始转换(参见:JLS第5章)。这就是说,这有一种明显的过早优化气味;在现实世界中,这没有什么区别。是的,我很好奇,这不是一个性能问题在Java 15 long上运行各种测试的速度比intI快7.5倍,我认为这是相关的,但不是全部,因为我们需要知道JRE在内部如何表示int和long,这将影响it执行转换的方式。@nhahtdh-可以安全地假设JVM(而不是JRE!)使用本机有符号32位和64位整数表示法表示int
和long
,并使用本机指令进行32到64位转换,和long
算术和比较。@nhahtdh整个问题基本上是无关的;您可以在数百万次加宽操作中节省几纳秒。由于这取决于实现,所以答案是,如果OP真的想知道性能差异,他们应该在JVM+硬件上进行测量。JLS只是说明JVM需要什么。@BrianRoach:我完全知道知道知道这个问题的答案并不能节省你的时间,因为有太多的其他事情会压倒你从中节省下来的任何时间。@BrianRoach的评论+1。。。尽管“数百万次加宽操作中的几纳秒”可能夸大了情况。。。一点。您可以在数百万次加宽操作中节省几毫秒。但你的基本观点是100%正确的。这很可能是无关紧要的