2012-02-27 5 views
1

Нужно ли беспокоиться о производительности в приведенном ниже примере и сохранять результат дорогого вызова, или компилятор узнает, что он может сделать дорогой звонок один раз?Оптимизация компилятора Java

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

Если результаты получают данные из let say database или из сети, данные изменяются. Поэтому логически это не будет сохранено. – user717572

+0

Это упростит код для простых случаев, которые могут быть встроены, и JVM (а не компилятор javac) может обнаружить, что побочных эффектов нет. –

ответ

2

Компилятор не будет (в общем) делать вызов только один раз, поскольку он может иметь побочные эффекты, или может быть изменчивым в его результате - он не мог знать, когда вы хотите, чтобы он игнорировал второй вызов, и когда вы хотели, чтобы он действительно повторите вызов. Вам нужно сохранить результат:

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

Как мог компилятор Java знать, что expensiveCall не имеет никаких побочных эффектов? В общем случае - не может. Также: вы можете перекомпилировать класс object в любое время без перекомпиляции текущего класса. И что произойдет, если expensiveCall получил побочные эффекты сейчас? Нет возможности автоматической оптимизации.

BTW: JIT-Compiler at runtime может иметь более подробную информацию. Но дорогие звонки обычно не учитываются для встраивания и, следовательно, также не для дальнейших шагов оптимизации.

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 увидеть оптимизации компилятора.

В вашем случае это ничего не оптимизирует.

Смежные вопросы