原文はこちら。
This article was written by Geoffrey De Smet (Lead and founder of OptaPlanner).
https://www.optaplanner.org/blog/2021/09/15/HowMuchFasterIsJava17.html
(訳注)日付に関する情報は原文のまま訳しています。
Java 17 (昨日リリースされました)が多数の新機能や改善を伴って登場しました。しかし、そうした新機能などのメリットを享受するためにはコードの変更が必要です。でもパフォーマンスについては別です。シンプルにJDKを置き換えれば、お金をかけずにパフォーマンスを改善できます。しかしながら、どれぐらい改善するのでしょうか?置き換える価値はあるのでしょうか?それでは、JDK 17、JDK 16、JDK 11のベンチマークを比較してみましょう。
Benchmark methodology
ハードウェア
CPU: Intel® Xeon® Silver 4116 @ 2.1 GHz (12コア / 24 スレッド)
RAM 128 GiB
OS: RHEL 8 x86_64
他に計算負荷のかかるプロセスを実行していない安定したマシン。
JDK (コンパイル、実行の両方に利用)
JDK 11
JDK 11 openjdk 11.0.12 2021-07-20
OpenJDK Runtime Environment Temurin-11.0.12+7 (build 11.0.12+7)
OpenJDK 64-Bit Server VM Temurin-11.0.12+7 (build 11.0.12+7, mixed mode)
JDK 16
JDK 16 openjdk 16.0.2 2021-07-20
OpenJDK Runtime Environment (build 16.0.2+7-67)
OpenJDK 64-Bit Server VM (build 16.0.2+7-67, mixed mode, sharing)
JDK 17
JDK 17 (downloaded 2021-09-06)
openjdk 17 2021-09-14 OpenJDK Runtime Environment (build 17+35-2724)
OpenJDK 64-Bit Server VM (build 17+35-2724, mixed mode, sharing)
JVMオプション
-Xmx3840M
は共通、明示的に利用するGCを指定-XX:+UseG1GC
(3個のJDK全てのデフォルト)-XX:+UseParallelGC
(高スループットGC)
Mainクラス
org.optaplanner.examples.app.GeneralOptaPlannerBenchmarkApp
(OptaPlanner 8.10.0.Final
の optaplanner-examples
モジュール)
各実行では11個のOptaPlannerで計画問題(employee rostering、school timetabling、cloud optimization)を解く。
Employee rostering
https://www.optaplanner.org/learn/useCases/employeeRostering.html
School timetabling
https://www.optaplanner.org/learn/useCases/schoolTimetabling.html
Cloud Optimization
https://www.optaplanner.org/learn/useCases/cloudOptimization.html
各計画問題は5分間実行、ログレベルはINFOに設定。ベンチマークは30秒のJVMのウォームアップから始まるが、これは破棄される。
(スタートアップ時の入力のロードのための数ミリ秒を除き)計画問題の解決ではI/Oはない。1個のCPUは完全に飽和状態で、コンスタントに多数の短命オブジェクトが作成され、GCがその後そうした短命オブジェクトを回収する。
ベンチマークでは1秒間に計算されるスコアの数を測定する(スコアがよいほど良い)。提案された計画問題の解答スコアの計算は簡単ではなく、すべてのエンティティと他のすべてのエンティティとの間の衝突をチェックするなど、多くの計算が必要である。
実行: 各JDKおよび各GCの組み合わせを順次3回実行する。この結果は3回の実行を平均したものである。
結果
Java 11 (LTS) と Java 16 を Java 17 (LTS) と比較

Average |
Cloud balancing |
Machine reassignment |
Course scheduling |
Exam scheduling |
Nurse rostering |
Traveling Tournament |
||||||
Dataset |
200c |
800c |
B1 |
B10 |
c7 |
c8 |
s2 |
s3 |
m1 |
mh1 |
nl14 |
|
JDK 11 |
103,606 |
96,700 |
274,103 |
37,421 |
11,779 |
13,660 |
14,354 |
8,982 |
3,585 |
3,335 |
5,019 |
|
JDK 16 |
109,203 |
97,567 |
243,096 |
38,031 |
13,950 |
16,251 |
15,218 |
9,528 |
3,817 |
3,508 |
5,472 |
|
JDK 17 |
106,147 |
98,069 |
245,645 |
42,096 |
14,406 |
16,924 |
15,619 |
9,726 |
3,802 |
3,601 |
5,618 |
|
11 → 17 |
8.66% |
2.45% |
1.42% |
-10.38% |
12.49% |
22.30% |
23.90% |
8.81% |
8.28% |
6.05% |
7.98% |
11.95% |
16 → 17 |
2.41% |
-2.80% |
0.51% |
1.05% |
10.69% |
3.27% |
4.14% |
2.63% |
2.08% |
-0.39% |
2.65% |
2.67% |

Average |
Cloud balancing |
Machine reassignment |
Course scheduling |
Exam scheduling |
Nurse rostering |
Traveling Tournament |
||||||
Dataset |
200c |
800c |
B1 |
B10 |
c7 |
c8 |
s2 |
s3 |
m1 |
mh1 |
nl14 |
|
JDK 11 |
128,553 |
121,974 |
292,761 |
48,339 |
13,397 |
15,540 |
16,392 |
9,887 |
4,409 |
4,148 |
6,097 |
|
JDK 16 |
128,723 |
123,314 |
281,882 |
45,622 |
16,243 |
18,528 |
17,742 |
10,744 |
4,608 |
4,348 |
6,578 |
|
JDK 17 |
130,215 |
124,498 |
262,753 |
45,058 |
16,479 |
18,904 |
18,023 |
10,845 |
4,658 |
4,430 |
6,641 |
|
11 → 17 |
6.54% |
1.29% |
2.07% |
-10.25% |
-6.79% |
23.00% |
21.64% |
9.95% |
9.68% |
5.63% |
6.80% |
8.92% |
16 → 17 |
0.37% |
1.16% |
0.96% |
-6.79% |
-1.24% |
1.45% |
2.03% |
1.59% |
0.94% |
1.08% |
1.89% |
0.96% |
Note | (ここでは表示されていないが)3回の実行の生データを見ると、Machine Reassignmentの数値(B1とB10)は、同じJDKとGCでの実行の間で大きく変動している(多くの場合、10%以上の差がある)。他の数字ではこのような信頼性の低さはないので、Machine Reassignmentの数値は無視した方が良いと思われるが、データのチェリーピックを避けるために、これらの結果と平均値にはMachine Reassignmentの値が含まれている。 |
G1GC versus ParallelGC on Java 17

Average |
Cloud balancing |
Machine reassignment |
Course scheduling |
Exam scheduling |
Nurse rostering. |
Traveling Tournament |
||||||
Dataset |
200c |
800c |
B1 |
B10 |
c7 |
c8 |
s2 |
s3 |
m1 |
mh1 |
nl14 |
|
G1GC |
106,147 |
98,069 |
245,645 |
42,096 |
14,406 |
16,924 |
15,619 |
9,726 |
3,802 |
3,601 |
5,618 |
|
ParallelGC |
130,215 |
124,498 |
262,753 |
45,058 |
16,479 |
18,904 |
18,023 |
10,845 |
4,658 |
4,430 |
6,641 |
|
G1 → ParallelGC |
16.39% |
22.67% |
26.95% |
6.96% |
7.04% |
14.39% |
11.69% |
15.39% |
11.50% |
22.50% |
23.01% |
18.20% |
Executive summary
平均して、OptaPlannerのユースケースでは、ベンチマークから以下のことがわかります。
- G1GCの組み合わせ(デフォルトGC)の場合、Java 17 は Java 11に比べて 8.66% 高速であり、Java 16 よりも 2.41% 高速である
- Parallel GCの組み合わせの場合、Java 17 は 6.54% Java 11よりも高速で、Java 16よりも0.37%高速である
- Parallel GC はG1 GCよりも 16.39% 高速である
驚きに値するものはありませんね。最新のJDKは高速であり、高スループットGCは低レイテンシGCよりも高速です。
Wait a minute here…
私たちがJDK 15でベンチマークしたとき、Java 15はJava 11よりも11.24%速いことがわかりました。
How much faster is Java 15?
https://www.optaplanner.org/blog/2021/01/26/HowMuchFasterIsJava15.html
で、Java 17のJava 11に対するゲインはJava 11のゲインに比べて少なくなっています。ということは、Java 17はJava 15よりも遅いということでしょうか?
いや、そうではありません。Java 17はJava 15よりも速いのです。以前のベンチマークは、異なるコードベース(OptaPlanner 8.10ではなく、OptaPlanner 7.44)で実行されていました。りんごとオレンジを比較してはいけません。
Conclusion
結論として、JDK17バージョンで得られたパフォーマンスは、少なくともOptaPlannerのユースケースにおいては、アップグレードする価値があります。
OptaPlanner – Constraint satisfaction solver (Java™, Open Source)
https://www.optaplanner.org/
さらに、これらのユースケースで最速のガベージコレクタは、G1GC(デフォルト)ではなく、依然としてParallel GCです。