Hotspot または Dalvik が、定数 (静的最終) int 値を返す最終メソッドへの呼び出しをインライン化するのに十分スマートであるかどうか、誰か教えてもらえますか? 理想的には、メソッド呼び出しは定数に置き換えられます。これは、クラスのロード時または JIT によるものである可能性があります。
これは、私が取り組んでいるいくつかのコードの設計に影響を与えます。
Hotspot または Dalvik が、定数 (静的最終) int 値を返す最終メソッドへの呼び出しをインライン化するのに十分スマートであるかどうか、誰か教えてもらえますか? 理想的には、メソッド呼び出しは定数に置き換えられます。これは、クラスのロード時または JIT によるものである可能性があります。
これは、私が取り組んでいるいくつかのコードの設計に影響を与えます。
final
少なくとも HotSpot VM では、答えは「いいえ、キーワードの不在または存在のために最適化は行われません」だと思います。しかし、他の要因によって最適化が行われる可能性があります。
Brian Goetz がこの記事で述べていることは次のとおりです(長い引用で申し訳ありません)。
Java のパフォーマンスに関する多くの神話と同様に、クラスまたはメソッドを最終的に宣言するとパフォーマンスが向上するという誤った信念が広く信じられていますが、ほとんど検証されていません。メソッドまたはクラスを final として宣言することは、コンパイラがメソッド呼び出しをより積極的にインライン化できることを意味します。これは、実行時にこれが確実に呼び出されるメソッドのバージョンであることを認識しているためです。しかし、これは単に真実ではありません。クラス X が最終的なクラス Y に対してコンパイルされたからといって、同じバージョンのクラス Y が実行時にロードされるわけではありません。そのため、コンパイラは、そのようなクロスクラスのメソッド呼び出しを最終的であろうとなかろうと安全にインライン化することはできません。メソッドがプライベートである場合にのみ、コンパイラはそれを自由にインライン化できます。その場合、final キーワードは冗長になります。
一方、ランタイム環境と JIT コンパイラーは、実際にロードされたクラスについてより多くの情報を持っており、コンパイラーよりもはるかに優れた最適化の決定を下すことができます。Y を拡張するクラスがロードされていないことをランタイム環境が認識している場合、Y が final であるかどうかに関係なく、Y のメソッドへの呼び出しを安全にインライン化できます (ただし、Y のサブクラスが Y のサブクラスである場合にそのような JIT コンパイルされたコードを無効にできる限り)。後でロードされます)。したがって、実際には、final は、グローバルな依存関係の分析をまったく実行しない愚かなランタイム オプティマイザにとっては有用なヒントになるかもしれませんが、その使用は実際には多くのコンパイル時の最適化を有効にするわけではなく、スマートなアプリケーションでは必要ありません。実行時の最適化を実行するための JIT。
少なくとも Java 5 では、 final が final でなくなった理由についての良い投稿もあります。
インライン化は、JIT コンパイラーがhot spotを検出した場合に実行する処理です。これは、バイト コードをマシン コードにコンパイルするために CPU 時間を費やす価値があると思われる、頻繁に呼び出されるバイト コード内のメソッドです。
JIT コンパイラーがメソッドをインライン化する可能性は非常に高いですfinal
(上書きできないため)。そのメソッドが定数値を返すだけの場合、可能性はさらに高くなります。
しかし、それは私の理解です-呼び出し元のメソッドがホットスポットでない場合、それはコンパイルされず、メソッドのインライン化はありませんfinal
.
(ドイツ語の情報源)
あるいは、Sootはそのような場合に Java バイトコードを最適化することが期待されます。