在Java中,创建一个对象和获取这个对象的值哪个更费资源?

4

比如说,我正在执行一个“if”块,在这个块中,我正在将某个数字的值与一个常量进行比较。那么像这样会更加昂贵吗:

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

或者:

int x = foo.getOb().getVal();
if( x == CONST_0 )
{
     ....
}
....
if( x == _CONST_N )
{
    ....
}
else
    ....

我知道这可能是一个愚蠢的问题。我认为第二种实现更快/更有效,但我很好奇为什么。我一直在思考原因,但由于我对Java的了解有点欠缺,所以几分钟内无法想出任何理由。

非常感谢任何答案!


1
生成您的示例的字节码并检查发生了什么。 - svlada
11
让你的编译器完成这种优化。如果你花时间担心这个问题,那么肯定有更重要的问题被你忽略了。 - Alex Feinman
5个回答

8
我认为你应该使用 switch 语句,这样你就不需要担心它了。
switch (foo.getOb().getVal()) {
    case CONST_0:
        .... 
        break;
    case CONST_N:
        .... 
        break;
    default:
        .... 
        break;
}

6
这不是对象创建。你正在创建对对象的引用。
您可以节省一些方法调用(在Java中它们非常有效)。
差异微不足道。而且很可能编译器会优化这样的事情。

1
他的 valint。所以 == 是唯一的选项。 - Alexander Pogrebnyak
不,x 不需要进行垃圾回收。它是在栈上分配的原始类型。 - Justin
即使它不是基本类型,x 只是对 getVal() 中对象的引用,而不是对象的额外实例。 - matt b
正确。已删除该部分(我自己说它不是一个新对象.. :)) - Bozho

3
假设getOb()getVal()只是返回引用而不进行计算,那么这两个代码片段在功能上是等效的。也就是说它们之间没有实际可辨别的差异。
在选择使用哪种形式时,这涉及到风格和偏好的问题,并且有点像预先优化(因为你可能会花费很多时间争论一个对应用程序性能没有任何可衡量影响的变化)的边界。

2

所以,明确一下,您建议他实现foo.isConst0(),foo.isConst1(),foo.isConst2()...... foo.isConstN()吗?看起来非常丑陋,我相信只需要使用foo.getObjVal(),然后根据值进行检查就足以满足“德摩尔定律”的限制。 - biggusjimmus
1
询问对象其内部状态违反了面向对象的原则。应该使用有意义的名称,例如foo.isInStateBar()等。抽象的例子在这里并没有太大帮助。最好使用真实、有意义的名称来表示。foo.isInStateBar()比foo.getObj().getVal()==3更好。 - mhaller

2
这主要取决于 getObj()getVal() 的实现方式。如果它们是昂贵的操作,那么你的第二个示例几乎总是更快的。但是,如果你只是担心方法调用的开销,那就不必担心了。JIT编译器通常可以内联方法调用,即使它没有这样做,其开销也很小。对于为本地变量在堆上分配内存同样如此,这些操作非常快,除非通过分析已经确定了性能 "瓶颈",否则现在想着什么会更快还为时过早。
有关过早优化的更多信息,请参见:何时算是过早进行优化? 作为一条准则,首先编写易于理解和正确的代码,并且只有在确定了明确的瓶颈时才尝试为速度/内存进行优化。通过先编写清晰易懂的代码,可以节省自己以及维护/调试代码的同事的时间和精力。

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