以下のケースではパフォーマンスを心配し、高価な呼び出しの結果を保存する必要がありますか、コンパイラーは高価な呼び出しを1回しか実行できないと認識していますか? JavaコンパイラはexpensiveCall
は副作用を持たないことを、知っている可能性がどのようにJavaコンパイラの最適化
String name;
if (object.expensiveCall() != null) {
name = object.expensiveCall().getName();
}
以下のケースではパフォーマンスを心配し、高価な呼び出しの結果を保存する必要がありますか、コンパイラーは高価な呼び出しを1回しか実行できないと認識していますか? JavaコンパイラはexpensiveCall
は副作用を持たないことを、知っている可能性がどのようにJavaコンパイラの最適化
String name;
if (object.expensiveCall() != null) {
name = object.expensiveCall().getName();
}
?一般的なケースでは、それはできません。また、現在のクラスを再コンパイルすることなく、いつでもobject
のクラスを再コンパイルすることができます。 expensiveCall
に副作用があるとどうなりますか?自動最適化のための方法はありません。
BTW:ランタイムのJITコンパイラは、より多くの情報を持っている可能性があります。しかし、高価な呼び出しは、通常、インライン化のために考慮されておらず、それゆえさらに最適化ステップには考慮されない。
String name;
MyResult result = object.expensiveCall();
if (result != null) {
name = result.getName();
}
あなたはまた、割り当てを行うために、構文を短縮し、同じ行に確認することができます:
String name;
MyResult result;
if ((result = object.expensiveCall()) != null) {
name = result.getName();
}
いいえ、あなたは一度だけ呼び出しを行うためにそれを書き換える必要があります。コンパイラは、副作用があるかもしれないので(一般的に)呼び出しを一度も実行しませんし、その結果に揺らぎもあります。それは、いつ2番目の呼び出しを無視したいのか、実際にもう一度電話をかける。あなたがmemoizationと呼ばれるものを探している
final ExpensiveCallResult nullableResult = object.expensiveCall();
String name;
if (nullableResult != null) {
name = nullableResult.getName();
}
:あなたは結果を保存する必要があります。 This questionは、Javaがネイティブではできないことを示しています。
コンパイル/ JITがその関数に副作用がないことが証明できる場合にのみ、一般にメモ化が可能です。だから、私はそれを信じないだろう。
しかし、結果を保存するのは本当に難しいですか?
String name;
ObjectType temp = object.expensiveCall();
if (temp != null) {
name = temp.getName();
}
将来的にはコンパイルとコンパイラの最適化を確認するために戻ってJADを使用してクラスをコンパイルすることができます。
あなたの場合は、最適化されません。
結果がデータを取得する場合は、データベースやネットワークからデータが変化します。したがって論理的には保存されません。 – user717572
これは、インライン化が可能な単純なケースのコードを単純化し、JVM(javacコンパイラではない)が副作用がないことを検出できます。 –