But we first want to get feature parity, before pivoting to performance. When we have feature parity, we'll run the Computer Language Benchmarks and post the results. That'll be fun to see!
Imho there is no way to do a fair comparison, as both implementations have completely different goals.
One thing that would be interesting is comparing the performance of some really simple command line program (e.g. `ls` or `cp` for small files) between Hotspot in interpreter mode, Jacobin and GraalVM native.
Jump tables for switch statements was only implemented last year. If you squint that's close to indirect threading, but still with at least one unnecessary conditional per op.
For the curious, here's their giant switch: https://github.com/platypusguy/jacobin/blob/c508ec50f55ef381... In practice compilers have always been finicky when it comes to coaxing them to emit jump tables from switch statements, and I bet this is especially truly for Go.
Around the time that change was made to Go, Andrew and I were looking at this and wondering how big of a performance hit it was and if there were a better way to structure that. I had a hunch that the compiler should be smart enough to not compile that as a switch/giant if block, and a quick trip to a disassembler showed it using binary search. This commit: https://github.com/golang/go/commit/1ba96d8c0909eca59e28c048... added the jump table and has some nice analysis on where it makes sense to do binary search vs jump tables.
As far as I can tell, with certain restrictions (that are fine in this case), it is pretty reliable at optimizing giant if/else blocks and switches.
It has been a fun project to play around with for someone like me who thinks this kind of stuff is fun and interesting but will probably never get a chance to work on it full time. Cool to see it noticed, though!
[*] until the latter will implement condensers: https://openjdk.org/projects/leyden/notes/03-toward-condense...
The optimizations in JDK 9 are for reducing the file size of the JDK (in terms of number of classes) when distributed with a standalone application, but that by itself doesn’t significantly affect startup time I believe, because classes are lazy-loaded only as required in any case.
Faster start up time is in the works with projects like coordinated restore at checkpoint which will let you start a JVM up in an already "warmed" state.
So this wouldn't help if I'm deploying a GUI app for Windows, for example.
Right now it's primarily useful for reducing start up times in AWS Lambdas and auto-scaling workloads.
Tangential, but a long time ago, I wanted to reuse a node.js slug library in .NET. I thought about trying to port it at first, but then I realized that this actual job didn't need to be terribly fast, so I instead embedded the Jurassic JS library into my code, and was able to load in the slug library that way directly). It wasn't especially fast (but actually faster than I thought it would be!), but it was certainly fast enough, and I didn't have to worry about not having feature parity.
(Saxon had since moved to transpiling the source code instead - the languages are close enough that this is fairly straightforward.)
The cool thing is that since this uses the Go garbage collector, you can create a very nice Go-native interface to that JVM code.
It seems the goals for this are purely academic and about figuring out how Java works. They'll probably just do a simple interpreter and not a JIT compiler. That would be good enough for a POC. Additionally, they already indicated that they'll use Go's garbage collector, which won't be setting speed records with this either. And Java's typical usage of memory might actually stress it out a bit. Then there is the standard library which is going to need plenty of support for things like Threads, IO, various synchronization primitives and locks, etc. Doing that in Go is going to be a bit interesting but probably doable. Alternatively, they might just interface with native code directly and bypass the Go ecosystem. They might even reuse some things from openjdk for that. Speaking of which, native code and JNI would need to be implemented anyway.
Writing something which is compatible with a specification is one thing, making it performant is another thing. For example it's not that hard to create a webserver from scratch but making it performant takes quite some effort.