Java 17 (released yesterday) comes with many new features and enhancements. However, most of those require code changes to benefit from. Except for performance. Simply switch your JDK installation and you get a free performance boost. But how much? Is it worth it? Let’s find out by comparing the benchmarks of JDK 17, JDK 16 and JDK 11.
Hardware: A stable machine without any other computational demanding processes running and with Intel® Xeon® Silver 4116 @ 2.1 GHz (12 cores total / 24 threads) and 128 GiB RAM memory, running RHEL 8 x86_64.
JDKs (used to both compile and run):
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
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 (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 options: -Xmx3840M and explicitly specify a garbage collector:
-XX:+UseG1GC for G1GC, the low latency garbage collector (the default in all three JDKs).
-XX:+UseParallelGC for ParallelGC, the high throughput garbage collector.
Main class: org.optaplanner.examples.app.GeneralOptaPlannerBenchmarkApp from the module optaplanner-examples in OptaPlanner 8.10.0.Final.
Each run solves 11 planning problems with OptaPlanner, such as employee rostering, school timetabling and cloud optimization. Each planning problem runs for 5 minutes. Logging is set to INFO. The benchmark starts with a 30 second JVM warm up which is discarded.
Solving a planning problem involves no IO (except a few milliseconds during startup to load the input). A single CPU is completely saturated. It constantly creates many short-lived objects, and the GC collects them afterwards.
The benchmarks measure the number of scores calculated per second. Higher is better. Calculating a score for a proposed planning solution is non-trivial: it involves many calculations, including checking for conflicts between every entity and every other entity.
Runs: Each JDK and each garbage collector combination is run 3 times sequentially. The results below is the average of those 3 runs.
Table 1. Score calculation count per second with G1GC on different JDKs
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%
Table 2. Score calculation count per second with ParallelGC on different JDKs
Note
Looking at the raw data of the 3 individual runs (not shown here), the Machine Reassignment numbers (B1 and B10) fluctuate a lot between runs on the same JDK and GC. Often by more than 10%. The other numbers don’t suffer from this unreliability.
It’s arguably better to ignore the Machine Reassignment numbers. But to avoid cherry-picking data concerns, these results and averages do include them.
When we benchmarked JDK 15, we saw that Java 15 was 11.24% faster than Java 11. Now, the gain of Java 17 over Java 11 is less. Does that mean that Java 17 is slower than Java 15?
Well, no. Java 17 is faster than Java 15 too. Those previous benchmarks were run on a different codebase (OptaPlanner 7.44 instead of 8.10). Don’t compare apples and oranges.
In conclusion, the performance gained in the JDK17 version is well worth the upgrade - at least for these use cases.
In addition, the fastest garbage collector for these use cases is still ParallelGC, instead of G1GC (the default).
Planned, planning education for real world stuff
Sign up for our monthly newsletter.
Continue reading
Blog
Timefold Solver 2.0 is coming
A major evolution of Timefold Solver arrives in March 2026. Version 2.0 removes legacy APIs, simplifies model development, introduces enterprise license keys, and provides a clear, automated upgrade path. This upgrade is designed for long-term maintainability and faster developer onboarding.
Blog
You Can’t Opt Out of Decisions
Every system makes decisions, even when no one is paying attention. This article explores how everyday heuristics quietly shape outcomes, and why optimization is a way to make those decisions intentional, transparent, and defensible.
Blog
Cooking is an integration project
Successful scheduling optimization is built before the algorithm even starts. With cooking as a clear, practical metaphor, this article shows how preparation, integration, and feedback shape real-world results.