marginalia_nu
11 hours ago
> I could show you benchmarks and memory savings of using primitive collections instead of boxed collections. If you need to see these to be convinced of the benefits of primitive collection support in Java, then you probably don’t need support for primitive collections in Java. No need to read any further. Please accept this complimentary set of eight boxes for your collection travels.
This is intellectually lazy. The performance characteristics of boxed vs unboxed primitives isn't forbidden knowledge from the necronomicon that only the select few are ready to partake in. Even if you think it's obvious, if you can back up an argument, go back up that argument. It makes your case stronger, it shows you know what you are talking about.
If not for other people, do it for yourself. Things that are too obvious to bother checking is generally where we're most likely to be wrong about things. This is true in life in general but it's especially true with the JVM and it's continuously evolving performance characteristics.
vlovich123
10 hours ago
I can believe it’s less of an issue for primitive smaller than long/double where the boxing/unboxing can be hidden through tagged values. But long and double specifically will always end up larger and slower. But the JVM doesn’t do this - instead it caches boxed representations of -128 to 128, true and false. This means any collection of not Boolean and not short/char will inherently at least use much more ram and have overhead accessing it.
marginalia_nu
7 hours ago
That's a good start that explains some of the memory overhead (along with the sizable Java object header), but we also need to take into account memory locality to explain why this is so much slower.
Main memory access is at worst case order of 100x slower than a cached read. With boxed primitives you very often looking and main memory access, whereas naked primitives can (when the planets align) amount to cached memory access.
cyberax
6 hours ago
Tagged pointers don't buy as much performance as you'd expect in Java. That's because the JVM is highly multithreaded, and the Java memory model guarantees memory safety (unlike in Go, for example). So every pointer load from RAM will need a check for the tag bits. And you end up with your code full of branches.
From practical experience, JVMs have had an option to use compressed pointers for inner fields for two decades ( https://wiki.openjdk.org/display/HotSpot/CompressedOops ). It saves a bit of RAM, but often results in slower code.
More recently, the new ZGC collector started using colored pointers, there's a good presentation about it: https://inside.java/2025/10/06/jvmls-zgc-colored-pointers/ It's also been a mixed bag, performance-wise.
jbellis
10 hours ago
This is extremely well trodden ground, and he's right. The world doesn't need him to spend time explaining that water is wet.
msgilligan
9 hours ago
And I think he's also acknowledging that not everybody has an application that needs these performance optimizations.
citizenpaul
7 hours ago
I have an unpopular opinion. I simply do not read anything on medium anymore. I in fact have a ublock rule that blocks the site so I do not accidentally go there or give them traffic anymore.
I saw go in the title so I just checked the HN comments first.