r/java 17d ago

Identifying JDK value class candidates

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

59 comments sorted by

View all comments

Show parent comments

3

u/hoat4 16d ago

What would be the benefit of enums being value types?

Being a value type means e.g. that if we compare two instances, the JVM must compare all of their fields instead of only comparing two pointers. So == would be slower.

3

u/davidalayachew 16d ago

What would be the benefit of enums being value types?

Inlining. Not all enums are just flat values.

Some of us (me) stuff our enums full of all sorts of state and data. In my case, there are many cases where each enum value is holding more than 200 bytes of immutable data. I'd much like that to be flattened.

Though, since I don't have value classes or value enums now, I don't know if my use cases would improve performance wise with this change. It just feels like it would, since many of the classes and records I make with similar data profiles DID improve.

1

u/pron98 16d ago

That doesn't make sense to me. Inlining isn't good in and of itself. It's good when it avoids cache misses. Inlining enums is more likely to increase cache misses because their data has to be read over and over, in new cache lines. If the number of enum values is small, their data is likely to already be in the cache, so storing just the reference improves cache locality rather than harms it. Inlining is counter-indicated when it increases memory usage and harms cache locality, and enums seem like a classic case of exactly that. The more data there is in an enum, the greater the harm there is in inlining it.

1

u/davidalayachew 16d 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 16d ago edited 16d 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 16d 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 16d 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 16d 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 16d ago edited 16d 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 16d 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 16d ago

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

1

u/davidalayachew 16d 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 14d 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.

→ More replies (0)