Java JITコンパイルを体感しよう
とりあえず体感してみよう
JITDemo.java
を使用してJITを無効にした時と有効にした時の処理時間を見てみます。
JITDemo.javaCopied!!public class JITDemo { public static void main(String[] args) { // ウォームアップ System.out.println("Warming up..."); for (int i = 0; i < 10000; i++) { performCalculation(); } // 実行時間の計測 System.out.println("Running test..."); long startTime = System.nanoTime(); for (int i = 0; i < 1000000; i++) { performCalculation(); } long endTime = System.nanoTime(); long duration = (endTime - startTime) / 1_000_000; // ミリ秒に変換 System.out.println("Execution time: " + duration + " ms"); } private static double performCalculation() { double result = 0.0; for (int i = 1; i < 1000; i++) { result += Math.sqrt(i); } return result; } }
-
コンパイル
Copied!!$ javac JITDemo.java
JITDemo.class
というファイルが生成されます
-
JITを無効にして実行する場合(インタプリターモード)
Copied!!$ java -Xint JITDemo Warming up... Running test... Execution time: 7688 ms
-Xint
オプションを使用します
-
JITを有効にして実行する場合(通常モード)
Copied!!$ java JITDemo Warming up... Running test... Execution time: 329 ms
処理時間の比較
- JITが無効な時:7688 ms
- JITが有効な時:329 ms
(7688 - 329) / 7688 * 100 ≒ 95.7(%)
も実行時間が短くなっていますね!
所感とまとめ
実は私、今回初めて-Xint
オプションを使用しました。JITの効果を体感しようと思っていたら、実は普段からJITの恩恵を授かっていたわけですね笑
以降はJITについて調べたことをまとめています。参考にしてください。
JITとは
JIT(Just-in-Time)コンパイルとは、Javaなどの一部のプログラミング言語における実行時の最適化技術の一つです。JITは、プログラムを実行するタイミングでコードを機械語にコンパイルすることで、実行パフォーマンスを向上させる役割を果たします。
JITコンパイルの仕組み
通常、Javaなどのプログラムは次のように実行されます。
-
ソースコードからバイトコードへのコンパイル(共通)
Javaコードはまず、Javaコンパイラ(javac)によってバイトコードに変換されます。このバイトコードは中間表現で、Java仮想マシン(JVM)上で実行されるように設計されています。
Copied!!ソースコード ▶ バイトコード(中間表現)
-
JVMによるインタプリタ実行の場合
JVMは、バイトコードを1命令ずつ解釈して実行するインタプリタとして機能しますが、この方法はCPUにとっては効率が悪く、処理が遅くなりがちです。
Copied!!ソースコード ▶ バイトコード(中間表現) ▶ 実行
-
JITコンパイルを使用して実行する場合
JITコンパイラは、プログラムの実行時に頻繁に使用される部分のバイトコードを機械語に変換します。この変換された機械語は、直接CPUで実行されるため、インタプリタ実行よりもはるかに高速に動作します。JITは特定のメソッドやループのように、繰り返し実行される「ホットスポット」に対してのみ最適化を行うため、効率的な動作が可能です。
Copied!!ソースコード ▶ バイトコード(中間表現) ▶ 機械語(JITコンパイラ) ▶ 実行
筆者の実行環境
Copied!!$ java -version openjdk version "11.0.24" 2024-07-16 OpenJDK Runtime Environment (build 11.0.24+8-post-Ubuntu-1ubuntu322.04) OpenJDK 64-Bit Server VM (build 11.0.24+8-post-Ubuntu-1ubuntu322.04, mixed mode, sharing)
Copied!!$ cat /etc/os-release PRETTY_NAME="Ubuntu 22.04.5 LTS" NAME="Ubuntu" VERSION_ID="22.04" VERSION="22.04.5 LTS (Jammy Jellyfish)" VERSION_CODENAME=jammy ID=ubuntu ID_LIKE=debian HOME_URL="https://www.ubuntu.com/" SUPPORT_URL="https://help.ubuntu.com/" BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" UBUNTU_CODENAME=jammy