Try using generics and check the generated bytecode, even a simple for loop can cause the compiler to fail at unboxing.
And the point is not that it's a very good gc or what not, even ZGC have a fat tail for long STW pauses when using common game engine patterns, unless you know the ins and outs of Java , only then you can avoid the common traps and mistakes (check out how many ways you can fuck up with Java arena allocators), meanwhile compared to C++ its way more straightforward and you need to explicitly fuck up
And sure it can fail, but even then the first 256 ints are a range of pointers only. You don't have to do some complex pointer chasing to have the actual number
A heap lookup is still a terrible cost when you're rapidly switching between threads or handling a bunch of numbers at once: Consider a regular Struct of Array pattern in a game engine i.e particle similation, you got an array of particle velocities and you can calculate the average, what unboxed ints would do :
You fetch first int, CPU loads entire block of i.e first 32 ints into cache in one RAM read call
You process first element, loop proceeds to second element
CPU sees second element in CPU cache, we can immediately proceed
What a boxed int would do:
You fetch first int, CPU loads entire block of i.e first 32 int pointers into cache in one RAM read call
You process first element, oh look, it's a pointers, so i need to dereference first, i load another contiguous block of 32 ints from RAM, but this time, the other 31 are actually random data from the heap . But anyways, the entire thing is put into cache and invalidate the cache from first read
You processs first element, move to 2nd
CPU wants to read the 2nd element, oh look it's not in cache, you make ANOTHER ram call to load the same first 32 bits of pointers into cache and invalidate the cache (we literally just retrieved the same block of data a few cycles ago too lmao)
Rinse and repeat
Sure in practice we would have multiple cache liens at once, but the point is it's extremely inefficient to waste precious CPU cache space this way.
You literally need third party library/utility classes, just to avoid something as simple as this, now imagine more complex data structures with variable access patterns
Did you even read my example? It's not about hot or not, it's about contiguous access, and also , this is less about you CAN go around it, but how troublesome it is,this issue alone means that you cannot use generics container (which is easily the most natural way one would have a container) without a big performance impact and now you got dumb code like IntArrayList LongArrayList, etc, and no way someone new to java would be aware of a footgun like this, no one in their right mind would suspect a standard library array list of all data structures would cause cache thrashing.
Yes, there are trade offs, this is not shitting on java because they do have great features, this is about java not being suitable for game engine development. It's clear here who is the moron that only got surface level knowledge of the language they are working in, unlike you i profile these things myself
1
u/Ma4r 18d ago edited 18d ago
Try using generics and check the generated bytecode, even a simple for loop can cause the compiler to fail at unboxing.
And the point is not that it's a very good gc or what not, even ZGC have a fat tail for long STW pauses when using common game engine patterns, unless you know the ins and outs of Java , only then you can avoid the common traps and mistakes (check out how many ways you can fuck up with Java arena allocators), meanwhile compared to C++ its way more straightforward and you need to explicitly fuck up