It's fascinating technology, but in my opinion too little, too late.
Compiling with GraalVM is still a pain and will not work out-of-the-box without modifications for any non-trivial project.
This is mostly, I believe, not GraalVM's fault, because it can only do so much within the confines of the existing ecosystem.
If only AoT compilation to native code would have been taken seriously from the start, if only gcj would have gotten more attention, we could have ended up with an ecosystem that is somewhat amenable to what GraalVM tries to do.
As much as I like GraalVM and wish it success, my prediction is that in a few years it will be in the same state gcj has been quite some years now.
gcj had a lot of problems beyond needing configuration of reflection metadata. It used a full reimplementation of the standard library, and it was never adopted by the wider Java community being largely just Red Hat's strategy for creating a fully open source Java implementation rather than something offering specific benefits to Java developers. In particular people thought it'd lead to faster code, but GCC was never designed for Java and the results were actually a fair bit slower iirc.
Native image is quite different. With this new release the compiled images can not only be faster than JIT compiled Java (wow) but also use way less memory and start instantly. At a stroke this is resolving one of the biggest complaints people have always had against JVM languages.
And as a consequence you're seeing adoption by the wider community. All the modern Java web frameworks support it now, and there's a metadata repository where it's collected for projects that haven't accepted it upstream yet [1].
Valhalla and the vector API for SIMD, yes. In theory, at that point, the only major performance difference between them would be GC vs manual memory management. Also: code size.
One interesting experiment that'd be worth trying is generating value types that wrap memory segments, as that's the new manual memory allocation API. You can do pretty sophisticated manual allocation with arenas and stuff, but you can't allocate Java objects into those segments. What you can do though, is create a "struct" using VarHandles that you can cast the segment to which then reads/writes through to the segment. This leads to the question of whether you can make a nice wrapper around such value types that yield C++ style manual memory allocation.
I'm not sure any of those are actually quite right.
Valhalla supports flattening, that's the whole point of it. To get that you need to have a type declared as a value type, and then put it into a non-null variable, field or parameter. At least that's how the current prototype works. If you do that then the compiler will fully inline the allocation into arrays, containing objects/structs, or the stack.
Valhalla started with monomorphization prototypes, although that went silent years ago. I don't know if it'll be delivered in the first version. But, it's an intended goal of the project to deliver.
As for the final point, could you evidence that? It's very hard to do direct comparisons here because they're usually compiling very different languages and Graal hasn't been optimized for C++. For example, Graal can compile many languages LLVM just doesn't even try to. Also, you'd really need to compare against the Oracle GraalVM (née GraalVM Enterprise) to see the best of what it can do. I'm curious what comparison you're thinking of when you say that, as Graal is an extremely advanced compiler by any measure.
There are JVM implementations, like Azul, that use LLVM for their AOT/JIT compilers, so the last point isn't really a plus for C++.
Java like C and C++, enjoys multiple implementations.
Regarding monomorphization, it is still open how much Valhala will go into that front.
Even if Java will never be as good as C++ in generics, there are several other issues that usually tend to have Java chosen for instead of C++, even if C++ wins in the microbenchmark games.
Likewise most options for running Java on the GPU aren't as feature rich as C++, and that is certainly an area where C++ will be dominating in decades to come.
I think the reality is that faster startup, smaller deployments, and lower memory usage is considered much more valuable today than it was when GCJ was an actively maintained project. It simply did not offer things people needed at that time. But now, the tradeoffs are different, and so the effort of going back and modifying existing code to support AOT compilation has a greater overall payoff than it did in the past, which is why people are pursuing it. It's the same reason .NET is adding full AOT support - because people want it now, and they want it now more than they did before.
I worked on gcj (and GNU Classpath) for a number of years. gcj's origins are in the embedded systems space, where our customers valued the small memory footprint and portability across processor architectures that were unlikely to get performant JITs. As we eased out of the embedded space, it was clear that jumping on the OpenJDK train was the right choice for Free Software-minded gcj/Classpath devs, as Sun adopted the GPL and GNU Classpath exception license. gcj was unlikely to ever catch up, and many of us were motivated by the idea of a Free Software Java solution, which Sun just handed to us.
> [...] my prediction is that in a few years it will be in the same state gcj has been quite some years now.
You make it sound like GraalVM is just for ahead-of-time compiling like gcj, but there's more to it than native image. It's possible GraalVM will be openjdk's jit compiler, for example.
This is one of my challenges with the branding of the project - it's not super clear to me what folks are talking about when they mention Graal related tech.
That alone I think can muddy the waters and can even hurt adoption. I wish they had clear and meaningful names for the specific distinct pieces of tech (even if there is some shared underpinnings).
Good point. It is fascinating technology, but to get development resources in the long run it needs management/sponsor attention and for that it needs a practical use case today. That, I think is AoT compilation and I believe that, unfortunately, it doesn't cut it there.
Everything has a cost though. The one thing we lose is the ability for hotspot to change its mind and recompile code based on usage patterns I've toyed with graalvm for some uses and ended up with lost performance. Also a key note is that it only supports a pretty naive serialgc right now which is a big limitation. Bellsoft has a parallelgc which probably plays a little better, but we're always going to need to play trade-offs until they can support the more robust GC impls
You can try to use Graal as a JIT compiler as well, in case of Scala for example that has a bit more indirection on average it can cause some speedups.
As someone on the outside looking at GraalVM with curiosity, is it even possible to use something like Poetry to manage the Python part? Would you do that? Would I even need a venv anymore? Where would its edges be? What are the limits?
How are we people practically putting this polyglot stuff into action?
Compiling with GraalVM is still a pain and will not work out-of-the-box without modifications for any non-trivial project. This is mostly, I believe, not GraalVM's fault, because it can only do so much within the confines of the existing ecosystem.
If only AoT compilation to native code would have been taken seriously from the start, if only gcj would have gotten more attention, we could have ended up with an ecosystem that is somewhat amenable to what GraalVM tries to do.
As much as I like GraalVM and wish it success, my prediction is that in a few years it will be in the same state gcj has been quite some years now.