最近有人告诉我,涉及较小整数的比较会更快,例如,
// Case 1
int i = 0;
int j = 1000;
if(i<j) {//do something}
// Case 2
int j = 6000000;
int i = 500000;
if(i<j){//do something else}
因此,案例1中的比较(if
条件)应该比案例2中的更快。在案例2中,整数将占用更多空间来存储,但这可能会影响比较,我不确定。< / p>
编辑1: 我在考虑i&amp;的二进制表示j,例如,对于i = 0,它将为0,对于j = 1000,它为1111101000(在32位表示中它应该是:22个零后跟1111101000,完全忘记了32位或64位表示,我的坏!)
我试着看一下简单比较程序的JVM规范和字节码,对我来说没什么用。现在的问题是java中的数字比较是如何工作的?我想这也将回答为什么(或者为什么不)任何案例会更快。
编辑2: 我只是在寻找详细解释,我并不担心微观优化
答案 0 :(得分:3)
如果您关心性能,您实际上只需要考虑将代码编译为本机代码时会发生什么。在这种情况下,重要的是CPU的行为。对于简单的操作,几乎所有的CPU都以相同的方式工作。
因此,案例1中的比较(如果条件)应该比案例2中的更快。在案例2中,整数将占用更多空间来存储,但这可能会影响比较,我不确定。
int
在Java中总是32位。这意味着它总是占用相同的空间。在任何情况下,数据类型的大小都不是很重要,例如short
和byte
通常较慢,因为原生字大小为32位和/或64位,并且必须从更大的类型和符号中提取正确的数据扩展它。
我试着看一下简单比较程序的JVM规范和字节码,对我来说没什么用。
JLS指定行为,而不是性能特征。
现在的问题是java中的数字比较是如何工作的?
它的工作方式与几乎所有其他编译语言的工作方式相同。它使用单个机器代码指令来比较这两个值,另一个用于根据需要执行条件分支。
我想这也将回答为什么(或者为什么不)任何案例会更快。
大多数现代CPU都使用分支预测。为了保持CPU管道满,它会尝试预测将采取哪个分支(在知道它是正确的分支之前),因此执行的指令没有中断。如果这很好用,分支几乎没有成本。当它错误预测时,管道可以填充分支的指令,这是错误的猜测,这可能会导致严重的延迟,因为它清除了管道并采取了正确的分支。在最坏的情况下,它可能意味着100个时钟周期延迟。 e.g。
请考虑以下事项。
int i; // happens to be 0
if (i > 0) {
int j = 100 / i;
说通常采取分支。这意味着管道可以加载一条指令,该指令在知道不会采用分支之前触发中断(或Java中的错误)。这可能会导致复杂的情况需要一段时间才能正确展开。
这些被称为Mispredicted branches简而言之,每个/大部分时间以相同方式运行的分支更快,突然改变或非常随机的分支(例如在排序和树数据结构中)将更慢
答案 1 :(得分:1)
在32位系统上Int可能更快,在64位系统上可能更长。 我应该为此烦恼吗?不,您根据自己的要求编码系统配置代码。微观选择永远不会奏效,它们可能引入一些前所未有的问题。
答案 2 :(得分:0)
小整数对象可以更快,因为java会将它们视为特定对象。
-128&amp;&amp;的所有整数值i&lt; = 127存储在IntegerCache内部类Integer
中