Hacker News new | ask | show | jobs
by Cyph0n 3553 days ago
Assuming this comes in Java 9, and compilation of code other `java.base` is possible, will this make Java a more solid competitor to Go? I guess it partly depends on how much they optimize the compiled binary size. Go does a really good job at static compilation, so it will be tough to compete.
4 comments

In benchmarks I've seen, Java already smokes Go on any benchmark except the second or so it takes the JVM to start up.

I'm not aiming this just at you, but I think many people (node.js users in particular come to mind) don't realise just how good the JVM is, performance-wise. I'm not a great fan of Java the language, but the JVM is top class.

HotSpot can run hello world in about 50msec, not one second. A lot of people's views of JVM startup time are hopelessly out of date.

The primary thing people seem to like about Go is that it produces single native binaries. You can do that with Java too (I gave an example of Avian further up the thread), but people don't tend to bother because distributing a single JAR is not much harder and avoids any assumptions about what OS the recipient might have. Go users seem invariably to be writing programs for their own use and Go doesn't really "do" shared libraries, so they don't ever encounter the problem of distributing a binary of the wrong flavour because they don't distribute binaries at all.

By the way, in Java 8 there's a tool that produces Mac, Linux and Windows standalone packages and installers that don't depend on any system JVM. I've used it to distribute software successfully, although I had to make my own online update system for it. In Java 9 it's being extended quite a bit with the new "jlink" tool that does something similar to static linking ... the output of jlink is either a directory that's a standalone JRE image optimised and stripped to have only the modules your app needs, or you can combine it with the other tool to get a MacOS DMG (with an icon, code signing etc), Windows MSI/EXE (ditto), or a Linux DEB/RPM/tarball.

This isn't a single file at runtime of course, it's a single directory, but basically any complex native app will have data files and some sort of package too so that's not a big deal.

Sorry, my Java startup time is also very out of date it seems. Thanks for the deeper detail.
Java has AOT compilation since ages, here is one example.

https://www.excelsiorjet.com/

Most commercial JDKs do support AOT compilation to native code, and alongside Java library and eco-system, it definitely makes it more than a solid competitor to Go.

The problem is that free AOT compilers never were a big match to the ones from commercial JDKs, and in this day and age, most developers don't pay for compilers unless forced to do so.

So Java AOT compilers are usually only used by enterprise companies.

Yeah I'm aware of Excelsior, but it would be cool to see AOT in OpenJDK.
Java AOT is compile JVM bytecode to native code during startup of JVM, which is different from Go's compile source to native and distribute platform specific binaries. So in this case, Java binary size remain same as before, which is .jar or .war binaries.

For Go, .go -> native

For Java, .java -> .class -> package .jar -> AOT native

For Go part I might be wrong, not working on Go professionally.

No, not during startup, AOT can happen at any time chosen by the developer or user: there's a command line tool that triggers it and I believe the plan is to integrate it with the "jlink" tool that produces standalone, app specific JRE images. So you can produce a native installer for each platform.
My understanding is that JVM bytecode is compiled to native before startup of the JVM, that is why it is called AOT ;)
that is an incorrect assumption. AOT step will include deadcode elimination. In that way - the Java way is a more sophisticated way combining platform independent bytecode and platform-specific machine code.
No it's not. Compilers such as the one in IBM's J9 have a switch setting to use AOT.
Go still has the feature of lightweight threads (goroutines) by default and great communication and synchronization primitives (channels, select) between them. For Java you still have to choose either real threads or from one of dozens of not-necessarily-compatible async IO frameworks (Netty, Grizzly, ...). How much that really matters depends on the type of your application. There's also emulation of Gos concurrency through Quasar - but again it's not as first class as Gos features.
Java also has green threads.

The JVM specification doesn't require OS threads, and in the early days all JVMs only had green threads.

Nowadays you can still get such JVMs, just not the OpenJDK.

Scala and Akka blow goroutines out of the water imo.