Gradle 8.5 fully supports compiling, testing and running on Java 21. Java updates frequently include optimizations that improve the performance of both the JVM and the Java applications running on it.
At the Devoxx Belgium presentation "With Java 21, Your Code Runs Even Faster But How is that Possible?", Per Minborg explains some of the optimizations shipped in Java 21 like Perform I/O operations in bulk for RandomAccessFile highlighting or Unroll by hand StringUTF16 and StringLatin1 polynomial hash loops, and what is better, these optimizations have an immediate impact without changing the java application because by direct usage or by transitive dependency use.
Following the previous Java 17 article, in this article we share the results of measuring an Android project with Java 21.
Nowinandroid
The project used is nowinandroid. The experiment is based on the commit f5b3ae5 of the main branch(12/22). At this point, the project was already using Gradle 8.5.
The only change applied was to update the AGP to 8.2.1 because it included the fix for the issue: JdkImageTransform fails when using JDK 21
Experiment methodology
- Two variants
- JDK 17
- JDK 21
- Scenarios:
assembleDebug
assembleRelease
testDemoDebug
lintDemoRelease
- Each variant/scenario runs 100 clean builds in GHA runners
- Memory configuration for all builds:
-Xmx6g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:+UseParallelGC -XX:MaxMetaspaceSize=1g
Results
First, we explore the overall build time for the different scenarios:
JDK 17 - Median (secs) | JDK 21 - Median (secs) | Improvement | |
---|---|---|---|
assembleDebug | 448 | 433 | 3.4% |
assembleRelease | 659 | 591 | 10.2% |
testDemoDebug | 334 | 320 | 4.3% |
lintDemoRelease | 306 | 296 | 3.3% |
In four evaluated scenarios, we are observing modest improvements in three of them, while the assembleRelease
scenario shows a significant reduction of 10% in build time.
Next, we explore where the improvements came from at the task level:
assembleDebug
Task | Diff Median (seconds) | Improvement |
---|---|---|
:app:mergeExtDexDemoDebug | 8.5 | 5.4% |
:app-nia-catalog:mergeExtDexDebug | 2.8 | 3.4% |
:app:mergeExtDexProdDebug | 2.3 | 10.2% |
:app:l8DexDesugarLibDemoDebug | 2.4 | 8.1% |
:app:hiltJavaCompileProdDebug | 1.7 | 7.3% |
assembleRelease
Task | Diff Median (seconds) | Improvement |
---|---|---|
:app:minifyDemoReleaseWithR8 | 49 | 18.2% |
:app-nia-catalog:mergeReleaseGlobalSynthetics | 35 | 29.6% |
:app-nia-catalog:mergeExtDexRelease | 29 | 19.9% |
:app-nia-catalog:l8DexDesugarLibRelease | 8 | 24.7% |
:app:minifyProdReleaseWithR8 | 7 | 9.9% |
testDemoDebugUnitTest
Task | Diff Median (seconds) | Improvement |
---|---|---|
:feature:foryou:testDemoDebugUnitTest | 3.4 | 7.6% |
:app:testDemoDebugUnitTest | 2.5 | 6.8% |
:core:designsystem:testDemoDebugUnitTest | 2.4 | 4.9% |
:core:data:testDemoDebugUnitTest | 1 | 10.2% |
:app:hiltJavaCompileDemoDebug | 1 | 9.6% |
lintDemoRelease
Task | Diff Median (seconds) | Improvement |
---|---|---|
:core:data:lintAnalyzeDemoRelease | 1.9 | 9.1% |
:core:designsystem:compileDemoReleaseKotlin | 1.5 | 6% |
:core:designsystem:lintAnalyzeDemoRelease | 1.2 | 6.2% |
:core:analytics:lintAnalyzeDemoRelease | 1.1 | 8% |
:core:datastore:lintAnalyzeDemoRelease | 0.9 | 12% |
Again the release scenario shows a significant improvement in the expensive R8 tasks.
Finally, we aggregated the absolute diff of the median for the tasks in each scenario providing the "serial" improvement using JDK 21:
Aggregated diff (seconds) | |
---|---|
assembleDebug | 37 |
assembleRelease | 158 |
testDebugUnitTest | 32 |
lintDemoRelease | 27 |
Data
Experiment scenario | Results |
---|---|
assembleDebug | https://github.com/cdsap/Pagan/actions/runs/7509423908 |
assembleRelease | https://github.com/cdsap/Pagan/actions/runs/7513465432 |
testDemoDebug | https://github.com/cdsap/Pagan/actions/runs/7520610718 |
lintDemoRelease | https://github.com/cdsap/Pagan/actions/runs/7516005997 |
Experiments spreadsheet: https://docs.google.com/spreadsheets/d/1wdXYp4ri5XUcBSGNc-ssUpjpcl1e-Pdns4-byNMyvwg/edit?usp=sharing
Final words
In this article, we explored how using JDK 21 enhances build efficiency in an Android project, particularly noting reduced build times. While some improvements were moderate, the assembleRelease tasks demonstrated notably greater enhancements.
The outcomes may differ based on the specific project, but considering the minimal adjustments needed, it's certainly worthwhile to experiment with this approach if you're utilizing Gradle 8.5.
Happy building!
Top comments (2)
Which jdk vendor was used in this analysis? I'm facing build error while using GraalVM CE 21.0.2
Hi @kshitijpatil, for this experiment I used the vendor oracle