Skip to content

Casual Machine Performance Test

Published: at 12:00 PM

Java Performance Showdown: JDK vs. GraalVM Native Image Across the Silicon Spectrum (Spoiler: Apple’s M-Series Shines)

Ever wondered how your machine really stacks up when it comes to Java performance? We’re not talking about hitting that absolute peak, hyper-optimized, once-in-a-blue-moon benchmark. Nah, this is about real-world, “let’s run it a couple of times and see what’s what” kind of performance. We’re looking for those ballpark differences that tell a story about the raw power – or lack thereof – under the hood.

The goal is simple: get a feel for the uplift between different systems, with a special curiosity about how Apple’s M-series MacBooks are changing the game. We’re pitting standard JDK compilation and runtime against the lean, mean, ahead-of-time compiled GraalVM Native Image.

NOTE This article is updated when someone I know (or myself) acquires a new machine.

The Ground Rules

To keep things fair and focused on pure CPU grunt, we made sure to rerun any initial Gradle runs. Why? Because nobody wants their benchmark tainted by Gradle downloading itself or pulling a mountain of dependencies. We’re interested in processing power, plain and simple.

These were the instructions given to some friends who had the machines required to flesh out this benchmark:

For this experiment, you’ll want your JAVA_HOME pointing to a GraalVM JDK.

The Test Bench Commands:

The Contenders & The Results:

Let’s dive into the numbers. We’ve got a diverse lineup, from old Intel MacBooks to modern M-series Machines, and even a couple of Linux and Windows machines thrown in for good measure.

SystemJDK Compile Time (ms)JDK Startup Time (s)Native Compile TimeNative Startup Time (ms)Spec NotesOS
2015 Macbook Pro30003.849436s (7m 16s)320MacOS
2020 Lemur Pro40008.052657s (10m 57s)938System76, i5 10210U 4c 40GBUbuntu Server 21.04
2019 Macbook Pro20003.786230s (3m 50s)4132.6GHz 6c i7MacOS
M1 Pro10002.071140s (2m 20s)207M1 Pro 8c 32GBMacOS
M2 Air10001.687205s (3m 25s)180M2 16GBMacOS
M2 ProN/AN/AN/AN/ACouldn’t get my hands on oneMacOS
M3 Pro6501.49079s (1m 19s)205M3 Pro 12c 36GB (6p,6e)MacOS
M3 Max6201.42966s (1m 6s)204M3 Max 16c 48GBMacOS
M4 Mac Mini6501.253125s (2m 5s)158M4 10c 32GB (4p,6e)MacOS
M4 Pro3331.30468s (1m 8s)189M4 Pro 14c 48GB (10p,4e)MacOS
M5 Max450ms1.196s59s (59s)129M5 Max 18c 48GB (12p,6e)MacOS
ITX Computer10002.410186s (2m 46s)172Ryzen 5700g 8c 16t 32GBPop!_OS 22.04 LTS
Dell 556014603.465217s (3m 37s)277Intel i7 32GBWindows 11 Pro

Note: Data for the M2 Pro was not available.

Dissecting the Data: The Apple M-Series Uplift is Real

Let’s be frank, the numbers speak volumes, especially when we zoom in on the Apple silicon.

JDK Performance:

GraalVM Native Image Performance:

This is where things get really interesting due to the ahead-of-time compilation.

Apple Silicon Through the Generations:

The M4 Pro remains king for raw JDK compile speed in our dataset. But the M5 Max reclaims ground in native startup, which is the more practically impactful metric for production workloads.

The Classic Upgrade Path: 2019 MacBook Pro → M3 Max → M5 Max

This is probably the most relatable progression — someone who’s been holding onto a solid Intel MacBook and wondering just how much they’ve been leaving on the table. Here’s the full picture:

The 2019-to-M3 Max jump is massive across the board. Going M3 Max to M5 Max brings more modest gains in compile throughput, but native startup continues to see meaningful improvement. If you’re on a 2019 Intel Mac, the upgrade argument is overwhelming regardless of which generation you land on. If you’re already on M3 Max, you’re getting diminishing but still real returns — with native startup being the metric that benefits the most.

What About the Non-Apple Camp?

Drawing Conclusions: The Ballpark Figures

  1. Apple’s M-Series is a Game Changer for Java Devs: The performance uplift from Intel-based Macs to the M-series (M1 through M5) is undeniable across both standard JDK tasks and GraalVM Native Image workflows. The Intel machines themselves span a 2.7x–3x spread just within their own camp, and yet even the best-performing Intel machine tested is blown out of the water by any M-series chip from M3 onward.
  2. Generational Gains Continue, But Shift in Character: Early M-series generations (M1 → M3) delivered broad improvements everywhere. Later hops (M4 → M5) show more targeted gains — native startup in particular keeps improving, while raw JDK compile speed appears to favor the M4 Pro’s architecture over the M5 Max’s higher core count.
  3. GraalVM Native Image is Blazing Fast (Especially Startup): The startup times for native-compiled applications are in a different league from standard JDK startup — milliseconds versus seconds. The M5 Max’s 129ms native startup is the new bar. While native compilation takes longer upfront, the runtime benefits are undeniable for latency-sensitive workloads.
  4. M-Series Excels at Native Compilation Too: While the Ryzen 5700g showed strong native compilation, the higher-end M3, M4, and M5 chips (Pro/Max) are leading the pack. The M5 Max crossing under 60 seconds for native compilation is a new milestone in our dataset.
  5. M-Series Air vs. Pro/Max: The M2 Air holds its own against older i7s and even the M1 Pro in JDK tasks, but the Pro and Max variants pull ahead in the heavier native compilation workloads. The M4 Mac Mini shows that even non-Pro M4 chips are formidable. The upgrade decision increasingly comes down to whether native compile time matters in your daily workflow.

The Bottom Line:

If you’re looking for a ballpark understanding, Apple’s M-series MacBooks, particularly the M3 and M4 generations, offer a stellar Java development experience. They provide substantial uplifts in both traditional JDK workflows and when diving into the world of GraalVM Native Images. While powerful desktop CPUs like the Ryzen 5700g can hold their own, especially in Linux environments, the efficiency and performance packed into Apple’s custom silicon for laptops (and now the Mac Mini) are hard to ignore.

The evolution is clear, and the speed is real. Happy coding!


Previous Post
GraalVM Native Spring Boot vs Go — Build, Boot, and Benchmark
Next Post
The Ultimate Guide to Spring Boot 4 Migration