我是否需要担心以下情况下的性能并保存昂贵的呼叫结果,或者编译器是否认识到它可以进行一次昂贵的呼叫?
String name;
if (object.expensiveCall() != null) {
name = object.expensiveCall().getName();
}
答案 0 :(得分:2)
编译器不会(通常)只执行一次调用,因为它可能有副作用,或者结果可能是不稳定的 - 它不可能知道你何时想要忽略第二次调用以及何时需要它实际上再次打电话。您需要保存结果:
final ExpensiveCallResult nullableResult = object.expensiveCall();
String name;
if (nullableResult != null) {
name = nullableResult.getName();
}
答案 1 :(得分:1)
您正在寻找名为memoization的内容。 This question表明Java本身不能这样做。
通常,只有在编译器/ JIT可以证明该函数没有副作用时才能进行memoization。所以我不会指望它。
但是保存结果真的很难吗?
String name;
ObjectType temp = object.expensiveCall();
if (temp != null) {
name = temp.getName();
}
答案 2 :(得分:0)
Java编译器怎么知道,expensiveCall
没有副作用?在一般情况下 - 它不能。另外:您可以随时重新编译object
类,而无需重新编译当前类。如果expensiveCall
有副作用现在,会发生什么?无法自动优化。
BTW:运行时的JIT编译器可能有更多信息。但昂贵的调用通常不考虑内联,因此也不考虑进一步的优化步骤。
答案 3 :(得分: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();
}
答案 4 :(得分:0)
将来,您可以使用JAD编译和反编译您的类,以查看编译器优化。
在您的情况下,它不会优化任何内容。