C++ では、メソッドを「インライン」で宣言でき、コンパイラはそれをインライン化する可能性があります。私が理解している限り、Java にはそのようなキーワードはありません。
JVMがそうすることを決定した場合、インライン化は行われますか? この決定に何らかの形で影響を与えることはできますか?
C++ では、メソッドを「インライン」で宣言でき、コンパイラはそれをインライン化する可能性があります。私が理解している限り、Java にはそのようなキーワードはありません。
JVMがそうすることを決定した場合、インライン化は行われますか? この決定に何らかの形で影響を与えることはできますか?
Java コンパイラーはインライン化を行うことができますが (略して早期バインド・メソッドの場合)、実際のインライン化は JIT コンパイラーによって行われます。JIT (HotSpot) コンパイラは、仮想メソッドをインライン化することもできます。それを操作する最善の方法は、シンプルで簡潔なコードを書くことです。ほとんどの場合、リフレクションを使用するコードではインライン化が許可されません。
それが役立つことを願っています。
「C++ では、メソッドを「インライン」で宣言でき、コンパイラはそれをインライン化します」 ... またはそうではありません。コンパイラは関数をインラインにするかどうかを自由に決めることができ、結果に実際に影響を与えることはできません。これは、コンパイラへのヒントにすぎません。
Java ではそのようなことはありません。コンパイラ (および後で最適化を実行している VM) は、メソッドを「インライン化」することを決定できます。
finalメソッドはインライン化される可能性が高いことに注意してください(派生クラスで上書きされる可能性があるため、コンパイラは非 final メソッドをインライン化できません)。最新の VM では、実行時に同様の最適化を行うことができます。VM は型にフラグを立て (型チェックを実行できるように)、コードをインライン化します。チェックが失敗した場合にのみ、元の最適化されていないポリモーフィック メソッド呼び出しにフォールバックします。
はい、JVM がそれを行うと決定した場合、それは可能です。影響を与える方法には、メソッドを static または final として設定することが含まれます。
もちろん、最も重要なことは、メソッドの構造がインライン フレンドリーである必要があるということです。短いことは役に立ちますが、最も重要なことは、ローカル変数とそのパラメーターのみを使用し、フィールドを使用せず、同じクラス内の他のメソッドへのメソッド呼び出しを最小限に抑える必要があることです。
ただし、そのような最適化を時期尚早に行うべきではありません。実際には事態を悪化させる可能性があります (他の潜在的な最適化を短絡させる可能性があるため)。JVM は、これらのヒントがなくてもメソッドをインライン化できることに気付くことがあります。
通常の関数と最終関数 (JVM ではインラインと呼ばれる) を比較すると、それらの間にパフォーマンスの向上がないことがわかりました。おそらく、関数呼び出しのオーバーヘッドはすでに非常に低くなっています。
注: パフォーマンスの評価にはボックスぼかしアルゴリズムを使用しました。