Live data from Hacker News

Value Classes Still Need Compiler Sympathy

johan-sjolen.github.io

21–30 of 51 posts

Re: Value Classes Still Need Compiler Sympathy

#23

Since being created, the Java pitch was "don't worry about low-level stuff like value/reference classes, a Sufficiently Smart Compiler will automatically pick the best option given your code and runtime profiling". What changed, why suddenly they adopt C++ features they explicitly excluded? https://wiki.c2.com/?SufficientlySmartCompiler

On the other hand, value semantics are just plain easier to reason about.

My 2 is your 2. We don't have different 2s because it makes no sense.

But sometimes you don't just want a 2, you want a pair (2,3). All of a sudden, my (2,3) isn't your (2,3), unless you call equals instead of ==, and remember to implement equals() (and that demands implementing .hashcode() too, and probably a toString() while you're at it). While it's easy to forget about if you've been using Java for a while, 2 gets passed by value, but your pair gets passed by pointer-value.

So I'd come at it from the other side. Pick a value representation of (2,3), reap the simplicity, and hope the sufficiently smart compiler is smart enough to do good things with it.

Re: Value Classes Still Need Compiler Sympathy

#24
post #12

Earlier quoted context omitted.

>What changed, why suddenly they adopt C++ features they explicitly excluded? Project Valhalla, which includes the effort to add value types was announced in 2014. They've been working on it for a while. As for "what changed" ... Back in 1990s when Java was conceived, there was an idea that CPUs in desktops had plenty of extra cycles that were being wasted and could therefore be used to reduce mental load on develope…

> So O(n) could be faster than O(log n) depending on the size of the data structure and interactions with RAM pre-fetch, etc. This has always been the case. The RAM effects only changed at which point the O(n) stops being faster than the O(log n) solution.

Apparently linear search now beats hashmap if you have less than TWO HUNDRED elements. Crazy!

Re: Value Classes Still Need Compiler Sympathy

#25
post #3

Since being created, the Java pitch was "don't worry about low-level stuff like value/reference classes, a Sufficiently Smart Compiler will automatically pick the best option given your code and runtime profiling". What changed, why suddenly they adopt C++ features they explicitly excluded? https://wiki.c2.com/?SufficientlySmartCompiler

Java is so dynamic that it's impossible to prove a class will only be used in "value friendly" ways. When objects have no identity the meaning of `==` is different, and the compiler would have to do some kind of whole program analysis to find out if there is any way an instance of the class could ever be checked for equality. That's hard when you have type erasure and polymorphism and runtime class loading. And even…

Many still don't get that while Java and C# (due to how it came to be after J++ lawsuit) are inspired by C++ for the syntax, it is mostly a mix of Smalltalk and Objective-C semantics in what is achievable, hence why a Smalltalk inspired JIT design was such a great addition early on.

Re: Value Classes Still Need Compiler Sympathy

#26

Since being created, the Java pitch was "don't worry about low-level stuff like value/reference classes, a Sufficiently Smart Compiler will automatically pick the best option given your code and runtime profiling". What changed, why suddenly they adopt C++ features they explicitly excluded? https://wiki.c2.com/?SufficientlySmartCompiler

First, it's not a C++ feature. In C++ you tell the compiler how to lay out objects in memory. Here you declare what properties your class has (e.g. whether it needs identity or not), and the compiler decides how to lay out each of its instances in memory, and may automatically do it in different ways in different places. So the principle that "you tell us what semantics you want and let the compiler figure out the implementation" remains in effect.

Second, the reason why the compiler cannot infer on its own that a class does or does not need identity without you declaring it is that the use of identity can be in a different module.

Re: Value Classes Still Need Compiler Sympathy

#27
post #6

Since being created, the Java pitch was "don't worry about low-level stuff like value/reference classes, a Sufficiently Smart Compiler will automatically pick the best option given your code and runtime profiling". What changed, why suddenly they adopt C++ features they explicitly excluded? https://wiki.c2.com/?SufficientlySmartCompiler

Even a smart compiler can't break the program semantics, and without a closed world assumption it simply can't assume that an entirely different part of the program doesn't expect to observe object identity for a type. Java is adding small, orthogonal features that amount to the same feature set as value types in other languages, but can be cherry-picked into existing code for partial advantages without significant c…

Nullability is coming later, and already with Panama you have plenty of room to do C like stuff.

Go isn't much better.

Re: Value Classes Still Need Compiler Sympathy

#28
post #27
post #6

Earlier quoted context omitted.

Even a smart compiler can't break the program semantics, and without a closed world assumption it simply can't assume that an entirely different part of the program doesn't expect to observe object identity for a type. Java is adding small, orthogonal features that amount to the same feature set as value types in other languages, but can be cherry-picked into existing code for partial advantages without significant c…

Nullability is coming later, and already with Panama you have plenty of room to do C like stuff. Go isn't much better.

You probably mean non-nullability.

And the big limitation is the rule that object writes can't tear - while this remains in place, it means that only tiny value classes will get any of the performance advantages being discussed, on regular processors. Specifically, the largest guaranteed atomic norma read/write in x86-64 is 64 bits, so any class that is larger than that (say, a pair of longs, or even a pair of ints until we get non-nullability) will not be compactible. An array of 1M (long, long) pairs will hold 1M pointers to (long, long) pairs allocated in the GC heap, forever. An array of 1M (int, int) pairs will as well, but in some future release when non-nullability makes it in, it will actually work as hoped.

Re: Value Classes Still Need Compiler Sympathy

#29
post #18

Since being created, the Java pitch was "don't worry about low-level stuff like value/reference classes, a Sufficiently Smart Compiler will automatically pick the best option given your code and runtime profiling". What changed, why suddenly they adopt C++ features they explicitly excluded? https://wiki.c2.com/?SufficientlySmartCompiler

The object header overhead was always present and expensive in massive arrays - the classic example would be the Point class that has two "double x, y". Realistically the value classes make sense most (only) if they are placed in arrays. In order to use tons of points you'd end up having two arrays, double[] x, double[] y... or go even with direct buffers. Personally, I don't care about the tiny optimizations possibl…

> Realistically the value classes make sense most (only) if they are placed in arrays.

Note that this is only relevant with the way Project Valhalla works for tiny value classes. A Point value class with two double coordinates can not be stored in line in an array, on an x86-64 processor, even after non-nullability is added to get one extra bit: the largest class that can be in-lined in that way has to be 64 bits in total size.

So, ultimately, the performance advantages are only going to materialize for []Integer and (in the future) []Long, and for some very specific byte-level processing code.

Re: Value Classes Still Need Compiler Sympathy

#30

Since being created, the Java pitch was "don't worry about low-level stuff like value/reference classes, a Sufficiently Smart Compiler will automatically pick the best option given your code and runtime profiling". What changed, why suddenly they adopt C++ features they explicitly excluded? https://wiki.c2.com/?SufficientlySmartCompiler

Yes, this was the idiom in the 90s, but Escape Analysis has not proven to be powerful enough to optimize away identity. And looking at all the edge-cases and possible data-races via tearing, declaring something as a value must be an explicit design decision that cannot be inferred by a compiler or optimizer alone.

Note that tearing is NOT a risk for value classes in Java - the JIT compiler is not allowed to optimize the layout of any value class that can tear on the current architecture (so, for any value class larger than 64 bits on x86-64).
Post reply on HN