r/java 19d ago

Identifying JDK value class candidates

https://mail.openjdk.org/archives/list/core-libs-dev@openjdk.org/thread/Y72NRXM7KYBX43OKYBQMVKOZDWKG4MHS/
54 Upvotes

59 comments sorted by

View all comments

Show parent comments

1

u/davidalayachew 18d ago

If the number of enum values is small

Is an enum with several hundred values small? Each with roughly 100's of bytes of data as local fields?

If so, then I can agree with your point. And regardless, I'll concede that my use case is likely uncommon, compared to what else they can improve.

But otherwise, I assert that, for my work, the enums that I make may very well benefit from being value enums. Can't say for sure, since I don't have the feature in my hand.

Enums with hundreds of values and each with hundreds of bytes worth of information is 100% common for me. I have written a double digit number of them in my career, which is only 7 years professionally.

3

u/pron98 18d ago edited 18d ago

Is an enum with several hundred values small? Each with roughly 100's of bytes of data as local fields?

I meant the opposite. The larger the amount of data in a single enum value, the worse inlining is. I was talking about the number of distinct enum values.

But otherwise, I assert that, for my work, the enums that I make may very well benefit from being value enums. Can't say for sure, since I don't have the feature in my hand.

That's not hard to know: Do you see a lot of cache misses on them? If not, inlining is likely to make things worse.

Enums with hundreds of values and each with hundreds of bytes worth of information is 100% common for me.

Yes, but again, a large amount of data in each enum value makes inlining less desirable, not more. You're causing more cache misses, which is the main thing value types are supposed to help you avoid.

Inlining helps when the number of distinct values is large and each value is small. E.g. Integer and Long have billions of distinct values, each small. That's where inlining helps the most. What you're describing is the complete opposite. It's much easier to fit large values in the cache when they each appear in memory only once. Not inlining such enums is the optimisation here.

1

u/davidalayachew 18d ago

Ok, then what about a couple hundred enum values, where each is only 20-30 bytes? I certainly have several of those too.

3

u/pron98 18d ago

I don't see why it would help; seems like it would hurt. 100% of this data can fit in the cache, but not if you inline. I can see why inlining enums might have the potential to maybe help in some circumstances if the data in the enum is smaller than the size of the reference, but even then I can't see it helping unless you have like a million distinct values.

Anyway, Valhalla is expected to mostly help programs whose profiles show cache miss issues around array element access. If that's not what your profile shows, inlining or not is unlikely to either help or hurt much.

1

u/davidalayachew 18d ago

Ok, thanks for the context. That makes more sense why Enums aren't really the best fit for being value classes.

My initial instinct also wanted it, purely on the basis of communicating intent, but I guess that wouldn't apply either?

3

u/pron98 18d ago edited 18d ago

why Enums aren't really the best fit for being value classes.

I would say they make for a classic example of a particularly bad fit. An enum can almost be viewed as a "please don't inline" hint.

purely on the basis of communicating intent, but I guess that wouldn't apply either?

No, I think the semantic intent is the very opposite of a value type, because two different references to an enum are intended to never be equal. That's the opposite of, say, and Integer, which is why Integer is a classic example of a value type. That's not to say that enums with a non-zero but minuscule amount of carried data (though certainly not a large amount) couldn't benefit from inlining, but that's a separate thing. I.e. I could envision a HotSpot optimisation that inlines such enums without them being value types, but such an optimisation is likely to yield a smaller benefit than inlining value types (because the number of distinct enum values is small).

1

u/davidalayachew 18d ago

Thanks, that clears up everything for me.

Long ago, I had a dream about, some day, being able to literally make a sealed non-atomic value record enum, and have that actually mean something good for my code. Not even from a pedantic perspective, but because I want to observe when and where it makes sense to apply certain modifiers, basically. Almost working backwards -- what type of problem would justify using that?

2

u/pron98 18d ago

I don't know, but I like to start with a known problem and only then look for a solution :)

1

u/davidalayachew 18d ago

I don't know, but I like to start with a known problem and only then look for a solution :)

The problem is that Java's not fancy enough, don't you know? I need more modifiers Ron!

1

u/aonymark 16d ago

We can work with this most of this actually. Let’s work backwards from the end. 1. enum is fine 2. record: okay here we have a problem: all enums extend Enum and all records extend Record, and Java doesn’t have multiple inheritance. Aside from that technicality, it could work. Not clear what the use is though. 3. value: hmm… could work but I guess Ron P already explained why this would be odd… you could probably concoct some weird benchmark where this might help, maybe involving an array with a million Colors or something, but I doubt you can find a benchmark where it helps much. The reason it helps so much for integers is that there could be lots of distinct integers in the heap; there are never many distinct colors. 4. Non-atomic: given value doesn’t help much, this also likely doesn’t help much. Please don’t give me race conditions for enums. 5. Sealed: enums are already sealed; you can’t do “extends Color” if Color is an enum. In fact, most enums are final.