int vs long比较会损害Java中的性能吗?

时间:2013-12-31 05:45:16

标签: java comparison int long-integer

比较int和long伤害表现?即。

int x = 1;
long y = 2;
if (x < y) doStuff();

而不是:

int x = 1;
int y = 2;
if (x < y) ...

是否有类型的转换?或者内存中的位布局是否允许直接比较? (即,对于int来说,long中的额外位都可以假设为0)

3 个答案:

答案 0 :(得分:17)

Java语言规范说明发生二进制数字促销,因此int转换为long。在实践中,转换实际上是微不足道的 - 在大多数现代硬件上,这并不是一项昂贵的操作。但是,整个问题不一定是性能问题;你使用很长时间不是因为性能,而是因为你需要能够管理更大的数值。

与性能问题一样,真正的答案是:

a)在成为问题之前,你不应该担心性能

b)在那个阶段,您应该剖析或进行测量以了解效果是什么。

答案 1 :(得分:3)

JLS是一个很好的参考,并且明确要求类型推广,但没有人谈到基本问题。

在机器级别(JIT编译后或JVM深层),具有64位ALU的处理器可能会使用一条指令进行64位至32位比较,以对32位进行符号扩展位操作数和第二个进行64位宽的比较,然后是围绕doStuff调用的分支。

对于intint 32位比较,可以省略符号扩展名。因此现代核心的区别在于一条指令或一个周期。

如果机器具有32位ALU,那么64位比较可能需要4条指令:compare,branch,test,branch。但它可以在3(带有借,子,分支的子)中使用正确的指令和/或额外的寄存器来完成。

intint需要两个:比较和分支。所以差异是1或2个指令/周期。

很少有程序在1或2个周期内产生有意义的性能差异。使用您需要的类型,以确保您的程序在未来十年左右的所有意外情况下都能正常运行。忘记几个周期。

NB 64位实际上会导致有意义的性能损失,这会使数据结构(以及较小程度的代码)大小膨胀2倍,从而使缓存和页面未命中变得更加频繁。但是你不应该提前担心这一点。

不幸的是,Java使得无法对未装箱的类型进行别名。从intlongfloat更改为double并返回是非常重要的:在许多情况下存在严重的语言缺陷。

答案 2 :(得分:1)

根据Java language specification,第5.6.2节,对数值比较运算符<<=>和{{的操作数执行二进制数字推广1}}。这意味着在比较之前>=将被提升为int

  

当运算符将二进制数字提升应用于一对操作数时,每个操作数必须表示可转换为数字类型的值,以下规则适用:

     
      
  1. 如果任何操作数属于引用类型,则进行拆箱转换   (§5.1.8)。
  2.   
  3. 应用扩展基元转换(第5.1.2节)来转换由以下规则指定的一个或两个操作数:

         
        
    • 如果任一操作数的类型为double,则另一个操作数将转换为double。
    •   
    • 否则,如果任一操作数的类型为float,则另一个操作数转换为float。
    •   
    • 否则,如果任一操作数的类型为long,则另一个操作数将转换为long。
    •   
    • 否则,两个操作数都将转换为int。
    •   
  4.         

    在类型转换后,如果有的话,将值集转换(第5.1.13节)应用于每个操作数。对某些运算符的操作数执行二进制数字提升:

         
        
    • 乘法运算符*,/和%(§15.17)
    •   
    • 数字类型的加法和减法运算符+和 - (§15.18.2)
    •   
    • 数值比较运算符&lt;,&lt; =,&gt;和&gt; =(§15.20.1)
    •   
    • 数字相等运算符==和!=(§15.21.1)
    •