一部のC++コードをJavaに変換していますが、インライン化された関数について何ができるのか疑問に思っていました。関数は(必要に応じて)VMによってインライン化され、これについて心配する必要はないと想定できますか?この動作を観察するためにプロファイルを作成するにはどうすればよいですか?メインの外部関数があり、その周りにforループをスローして、100万回の呼び出しを発生させたとします。VMがますますインライン化するにつれて、改善が見られると期待する必要がありますか?
1 に答える
はいJavaはインラインメソッド呼び出しを行います。インライン化はJITコンパイラによって実行されるため、バイトコードファイルを調べてもわかりません。
特定のメソッド呼び出しに対して実際にインライン化が行われるかどうかは、メソッド本体のサイズ、および呼び出しがインライン化可能かどうかによって異なります。(メソッド呼び出しにディスパッチが含まれる場合...不要なディスパッチを削除するように設計された一連のグローバル最適化がJVMに行われた後、インライン化することはできません。)
同じことが、外側のメイン関数を使用した例にも当てはまります。メソッド本体の大きさによって異なります。一方、メソッドの実行にかなりの時間がかかる場合、最適化の相対的な重要性はそれに応じて低下します。
私のアドバイスは、この段階ではこのようなことを心配しないことです。コードを明確かつ単純に記述し、JITコンパイラに最適化の問題を処理させます。アプリケーションが機能しているときは、アプリケーションのプロファイルを作成して、手動で最適化する価値のある「ホットスポット」がコードにあるかどうかを確認できます。
しかし、私はこれをVisual VMのようなもので見ることができるはずですよね?つまり、最初はインライン化が行われず、その後、インライン化されるものが増えるため、外部メソッドの平均時間がわずかに短縮されます。
メソッド本体の実行に関連して呼び出しを行うのに費やされた時間によっては、観察できる場合とできない場合があります。(プロファイリングは、多くの場合、プログラムカウンターのサンプリングに依存します。コードの特定の領域のサンプル数が少なすぎる場合、およびその他の理由で、報告された時間が不正確になる場合があります。)
また、使用しているJVMによっても異なります。すべてのJVMが、以前に最適化したコードを再最適化するわけではありません。
最後に、JVMにJITコンパイラによって出力されたネイティブコードをダンプさせる方法があります。それはあなたに何がインライン化されたかについてあなたに決定的な答えを与えるでしょう...あなたが機械の指示を読む準備ができているなら。