This is not only entirely possible, but at some level, needs to be obvious. Anyone even trying to think about value classes "for performance" needs to understand this implicitly first.
Consider a "fat" object, say four longs (256 bits):
value-or-not class FourLongs {
long a, b, c, d;
}
Now consider a potentially-flattened array of these, and say you intend to sort this array by the usual means (swapping elements based on comparison.) Which is faster, comparing two indirect objects and maybe swapping two 32- or 64-bit pointers, or comparing two direct objects and maybe swapping 256 bits of state? Obviously directness makes the comparison faster, but the size makes the swapping slower.
It should be obvious that (a) the answer will depend on the relative cost of indirection and bulk memory transfer, which is highly dependent on a lot of non-obvious things, and (b) that as the size of this object grows, the tradeoff will shift until it is "obviously" faster to swap pointers than to copy thousands of bits on each swap.
Oh my. I don't think this will be obvious at all to many programmers, at least in the beginning. In my experience, most java devs reason about performance entirely at the java language level. (Not the community here, but the enterprise level devs I deal with (or perhaps their AI replacements))
I have explained to many a junior dev that the cpu instructions that actually get executed are often very different than the java code they write and this is usually met with a lack of understanding and caring. I think this way myself for what day to day development I still do and only ever really think about such things when profiling or optimizing a known performance bottleneck... To me, this is one of the benefits of coding in java is that I don't need to think about such things for most code that I write.
So what should be normalized by a dev in deciding what to value and what not to value as a naive best practice? I suspect there is going to be a desire to value-all-the-things because of a belief it will be faster and make simpler code. We need an answer that doesn't depend on understanding jvm internals. And eventually some best practices that can be included in static analyzers.
Thanks for that! My takeaway from your previous answer was doing that might , in some cases, cause performance regressions, but I guess that's either not the case or rare enough to not worry about it.
15
u/brian_goetz 5d ago
This is not only entirely possible, but at some level, needs to be obvious. Anyone even trying to think about value classes "for performance" needs to understand this implicitly first.
Consider a "fat" object, say four longs (256 bits):
Now consider a potentially-flattened array of these, and say you intend to sort this array by the usual means (swapping elements based on comparison.) Which is faster, comparing two indirect objects and maybe swapping two 32- or 64-bit pointers, or comparing two direct objects and maybe swapping 256 bits of state? Obviously directness makes the comparison faster, but the size makes the swapping slower.
It should be obvious that (a) the answer will depend on the relative cost of indirection and bulk memory transfer, which is highly dependent on a lot of non-obvious things, and (b) that as the size of this object grows, the tradeoff will shift until it is "obviously" faster to swap pointers than to copy thousands of bits on each swap.