Java のバージョンを上げるだけで、プログラムは速くなるのか

よく Java の実行バージョンを上げるだけで速くなるという話を聞きます。 でも、本当にそうなのでしょうか。また、本当だとしたらどれぐらい速くなるのでしょうか。

そこで、簡単なプログラムで実験してみました。

実験概要

実験用に、数独を解く Java のプログラムを作成しました。 このプログラムは単純な演算を繰り返し行ってるだけなので、Webアプリケーションのような複雑なプログラムとはおそらく傾向が違いますが、参考程度にはなるかなと思います。

これをJava 1.1 でコンパイルし、Java 1.1 ~ 12 の各 Oracle JDK (32bit/64bit) で数独100万問のデータセットを読み込んで解き終わるまでの時間を測定しました。1

細かい測定条件は以下の通り。

  • 実行環境
    • Windwos 10 Home 1809 (64bit)
    • Intel Core i7-7500 CPU @ 2.70GHz
  • Java の実行オプション
    • -mx512m -ms512mを付与2
    • Java 1.3.1 以降は、-server を付与3
  • 測定方法
    • 各バージョンごとに5回測定し、中央値を取得

実験結果

処理は二つのパートに分かれているので、その処理ごとグラフ軸を分けました。

  • 数独100万問のデータセットを読み込む処理 (下図の青い部分)
    • この部分は、主に GC の性能に左右される
  • 数独を解く処理 (下図の赤い部分)
    • この部分は、主に JIT 最適化の性能に左右される

その実験結果がこちら。 処理時間(ms)

グラフの元データ...

|Java|Version|データ読み込み(ms)|数独解析(ms)|合計(ms)| |--:|--:|--:|--:|--:| |Java 1.1 (32bit)|1.1.8|8,313|4,231|12,544| |Java 1.2 (32bit)|1.2.2_017|6,647|4,360|11,006| |Java 1.3 (32bit)|1.3.0_05|10,747|6,905|17,652| |Java 1.3.1 (32bit)|1.3.1_28|7,647|5,093|12,740| |Java 1.4 (32bit)|1.4.0_04|8,061|4,741|12,802| |Java 1.4.1 (32bit)|1.4.1_07|7,810|4,796|12,606| |Java 1.4.2 (32bit)|1.4.2_19|3,437|3,281|6,717| |Java 5 (32bit)|1.5.0_22|3,050|3,289|6,338| |Java 6 (32bit)|1.6.0_45|3,530|4,077|7,607| |Java 7 (32bit)|1.7.0_80|3,411|3,211|6,622| |Java 8 (32bit)|1.8.0_202|3,239|3,257|6,496| |Java 6 (64bit)|1.6.0_45|5,029|3,312|8,341| |Java 7 (64bit)|1.7.0_80|7,019|3,148|10,167| |Java 8 (64bit)|1.8.0_202|5,050|3,054|8,104| |Java 9 (64bit)|9.0.4|2,101|2,961|5,061| |Java 10 (64bit)|10.0.2|2,056|3,054|5,110| |Java 11 (64bit)|11.0.3|1,922|3,343|5,265| |Java 12 (64bit)|12.0.1|1,934|3,422|5,356|

考察

「今回のプログラムでは」という前提が付きますが、データから以下のことが見て取れます。

  • Java 1.1 に比べて、最近の Java は2倍以上速くなっている
  • Java 1.3 で急激に遅くなっている。まだ、HotSpot が成熟していなかった?
  • Java 1.4.1 までは遅かったが、Java 1.4.2 でぐっと速くなっている
  • Java 6 ~ 8は、64bit VM より 32bit の方がデータ読み込みが速い
  • Java 9 でぐっと速くなっている

まとめ

Java のバージョンを上げるだけで、プログラムは速くなる。


  1. 後方互換性があるので、Java 1.1 でコンパイルしたクラスファイルは、以降のバージョンでもそのまま動きます。

  2. 「あれ -Xmx -Xms じゃないの?」って思うかもしれませんが、Java 1.1 ではこのオプションは -mx -ms になっています。Java 1.2 で VM オプションの -Xmx -Xms に変更になったのですが、いまだに -mx -ms も使えます。

  3. このオプションがないと HotSpot Client VM が使われてしまい、倍ぐらい遅くなります…。

  4. Concurrent Mark Sweep Garbage Collector。このGCについての詳細は、KUBOTA Yuji さんの資料を参照。

  5. https://twitter.com/skrb/status/1161642952420016130