> You want project Valhalla, or more specifically Value Objects, which are in preview [0]. If you really want the highest performance related to cache accesses, you want to arrange things as SoA (struct of arrays) anyway, which has approx 0 object overhead and doesn't require Value Objects.
SoA requires unboxed arrays, otherwise it defeats the purpose. I may have been wrong about int[] being boxed (it seems to be unboxed in most implementations), but the fact that ints still auto-promote to Integer in certain circumstances is just ridiculous for any kind of low-level programming.
It's also hilarious that Value Objects are still in preview. Even C# has had structs (value semantics) since forever.
> This is silly. This happens with all other languages, and Java will give you better results on average. Use a different compiler or runtime for your C code, or run it on a different processor architecture, and have fun tuning your code.
This is false. structs in C or C++ don't have a language-imposed overhead. They may have different sizes depending on the alignment requirements of the platform.
> The Vector API [1] is available in preview.
Also hilarious. It's 2024.
> It's widely understood that doing the opposite has been perhaps one of the largest mistakes in the history of the industry.
Checking every single array access in a tight loop, for example, is stupid. It's the naive, dumb, and inefficient way of doing it (i.e., the Java way.) The right way to do it is to enforce up front that the index may never be out of bounds. Ada helps with this by having user-defined ranges and integer types, for example.
> What does this even mean? An int[] is a linear array of 32-bit int values in memory.
Yes, I think I botched that one, but see also my comment above.
> Are we now just talking about a small slice of people who write bad code?
No, I am talking about Java.
> Ah, ok. Have a fine day.
Oh, and how does Java do low-level systems programming without unsigned integer types, lol? Oh, yeah, you need to cast to/from the next largest integer representation so that you can encode all of the positive values. And you better hope you don't need more than the native size, because then you get fuck-boxed into Integer (see my comment above.) Fucking hilarious, y'all.
Also, you don't even have a guarantee that a variable is allocated on the stack even when the dumbest compiler can tell it's bound by function scope. You need to hope that the JIT will do it, and from my past experience in Android (which this post is about), it doesn't. This is why, for example, if you look at the math library of LWJGL [1], all functions are defined to mutate one of the arguments, they never allocate a new vector to return. This is just completely stupid because mathematical vectors should have value semantics and the compiler optimize the fuck out of them. (Don't get me wrong, I love LWJGL and the guys. This is a criticism of the language, not the library; they are doing the best they can given the language's stupid decisions.)
[1] https://github.com/JOML-CI/JOML/blob/main/src/main/java/org/...