在Java中,创建对象或获取对象值的成本更高吗?

在Java中,创建对象或获取对象值的成本更高吗?,java,performance,Java,Performance,比如说,我通过一个“if”块,在这个块中,我将某个数字的值与一个常数进行比较。这样会不会更贵: if( foo.getOb().getVal() == CONST_0 ) { .... } .... if( foo.getOb().getVal() == _CONST_N ) { .... } else .... 或: 我知道这似乎是个愚蠢的问题。我认为第二个实现更快/更高效,但我很好奇为什么。在过去的几分钟里,我一直在想原因,但我实在想不出什么,因为我对Java

比如说,我通过一个“if”块,在这个块中,我将某个数字的值与一个常数进行比较。这样会不会更贵:

if( foo.getOb().getVal() == CONST_0 )
{
     ....
}
....
if( foo.getOb().getVal() == _CONST_N )
{
     ....
}
else
     ....
或:

我知道这似乎是个愚蠢的问题。我认为第二个实现更快/更高效,但我很好奇为什么。在过去的几分钟里,我一直在想原因,但我实在想不出什么,因为我对Java的知识……有点缺乏


谢谢你的回答

这不是对象创建。您正在创建对对象的引用

您节省了一些方法调用(在Java中,它们非常有效)

差别可以忽略不计。编译器不太可能优化这些东西。

假设
getOb()
getVal()
只是返回引用而不进行计算,那么这两段代码在功能上是等价的。这意味着它们之间没有真正明显的区别


关于使用哪种表单的争论最终归结为风格和偏好的问题,并且接近于先发制人的优化(因为您可能会花费大量时间来争论做出一个对您的应用程序的性能没有可测量影响的更改)。

这实际上取决于
getObj(
)并实现了
getVal()
。如果它们是昂贵的操作,那么是的,您的第二个示例几乎总是更快。但是,如果您只关心方法调用的开销,请不要担心。JIT编译器通常可以执行内联方法调用,即使没有,开销也很小。与本地变量在堆上的分配类似,这些操作非常快,除非您已经通过分析确定了性能“热点”,否则现在就开始考虑什么将执行得更快还为时过早

有关过早优化的更多信息,请参见此处:


通常,首先编写代码,使其易于理解和正确。只有当你发现了一个明显的瓶颈时,你才应该开始尝试优化速度/内存。通过先编写清晰的代码,您可以节省您自己和试图维护/调试代码的同事的时间和挫败感。

示例代码违反了标准。 应该是

if( foo.isConst0() )
{
    ....
}

无论如何。另外,

在我看来,您应该使用switch语句,在这种情况下,您不需要担心它

switch (foo.getOb().getVal()) {
    case CONST_0:
        .... 
        break;
    case CONST_N:
        .... 
        break;
    default:
        .... 
        break;
}

为您的示例生成字节码,并检查您的编译器执行此优化时所遇到的问题。如果你把时间花在担心这件事上,你肯定会忽略一些更重要的问题。他的
val
int
。所以
==
是唯一的选择。没有
x
将不需要垃圾收集。它是在堆栈上分配的基元类型。即使它不是基元类型,
x
只是对
getVal()
中对象的引用,它也不是objectCorrect的额外实例。删除了那个部分(我自己说它不是一个新对象…:),所以,要清楚,你建议他实现foo.isConst0(),foo.isConst1(),foo.isConst2(),foo.isConstN()?看起来非常难看,我很确定只要有foo.getObjVal(),然后检查值就完全符合Demeter的“定律”。询问对象的内部状态违反了OO。应该有有意义的名称,例如foo.isInStateBar()等。抽象的例子在这里帮助不大。最好用真实的、有意义的名字看。foo.isInStateBar()优于foo.getObj().getVal()==3
switch (foo.getOb().getVal()) {
    case CONST_0:
        .... 
        break;
    case CONST_N:
        .... 
        break;
    default:
        .... 
        break;
}