2012-02-27 131 views
1

在下面的例子中,我是否需要担心性能,并保存昂贵调用的结果,还是编译器意识到它可以执行一次昂贵的调用?Java编译器优化

String name; 
if (object.expensiveCall() != null) { 
    name = object.expensiveCall().getName(); 
} 
+1

如果结果从数据库或数据库获取数据,则数据会发生变化。所以逻辑上它不会被保存。 – user717572 2012-02-27 17:45:55

+0

它将简化可以内联的简单案例的代码,并且JVM(不是javac编译器)可以检测到没有副作用。 – 2012-02-27 18:05:48

回答

2

编译器不会(通常)只进行一次调用,因为它可能有副作用,或者结果可能不稳定 - 它不可能知道什么时候你想让它忽略第二个调用,并且当它实际上需要它时再次拨打电话。您需要保存结果:

final ExpensiveCallResult nullableResult = object.expensiveCall(); 
String name; 
if (nullableResult != null) { 
    name = nullableResult.getName(); 
} 
0

Java编译器怎么知道,expensiveCall没有副作用?在一般情况下 - 它不能。另外:您可以随时重新编译object的类,而无需重新编译当前的类。如果expensiveCall有副作用现在会发生什么?没有办法自动优化。

顺便说一句:JIT编译器在运行时可能有更多的信息。但昂贵的调用通常不考虑内联,因此也没有进一步的优化步骤。

0

不,你将需要重写它只能拨打电话一次:

String name; 
MyResult result = object.expensiveCall(); 
if (result != null) { 
    name = result.getName(); 
} 

您也可以缩短语法来进行分配,并在同一行检查:

String name; 
MyResult result; 
if ((result = object.expensiveCall()) != null) { 
    name = result.getName(); 
} 
1

您正在寻找名为memoization的物品。 This question表明Java本身不能做到这一点。

一般而言,只有在编译器/ JIT可以证明该函数没有副作用时才可以进行记忆。所以我不会指望它。

但是真的很难保存结果吗?

String name; 
ObjectType temp = object.expensiveCall(); 
if (temp != null) { 
    name = temp.getName(); 
} 
0

在将来你可以编译和反编译类回来JAD看看编译器优化。

在你的情况下,它不会优化任何东西。