Back when I wrote Clojure professionally, using GraalVM to generate a native executable of things like clj-kondo basically eliminated the startup latency.
I've been out of the Clojure ecosystem for some time now -- has GraalVM solved the slow start problem? I remember the 1-2 second start up time being a deal breaker for many applications.
I've only done one project with GraalVM and I've been pretty happy with it in regards to faster startup time.
I was doing stuff in Clojure. Clojure is a great language but it tends to have very slow startup times, even by JVM standards (it's not weird for a large Clojure program to take 5-6 seconds to start. Even a "hello world" can take upwards of a second or two). Graal mostly Just Worked with the standalone uberjar produced by Leiningen and created an executable that started in about 3 milliseconds. It was amazing.
While the lack of proper reflection support was a little annoying, it actually wasn't as horrible with Clojure as you might think; most problems were fixed with basic type hinting, and all but one Clojure library I used (http-kit) worked flawlessly.
Interesting; I've been using GraalVM to compile my Clojure JAR files for command line tools. Doing a basic Unix `time` command, the startup time for that is about 20 milliseconds, well within my tolerance threshold of a command line application.
That said, the executables for GraalVM are enormous, so I'm absolutely open to something comparable that avoids that. I'll give Babashka an install and play with it.
After hearing about GraalVM first time at a PolyConf talk last year I sat down with one of the GraalVM folks and we (well, I was just providing info) did a few performance measurements if this could speed up the startup time (especially for leiningen tasks) - the preliminary results were pretty cool.
So if you're using Clojure and Leiningen and are annoyed by the long startup times... there's potential :)
For me the most interesting part is how it gets rid of the JVM startup time.
So there are two parts to the solution: The first part is Small Clojure Interpreter (sci) which is a "(subset of) Clojure written in Clojure", so kind of McCarthy for Clojure. A cool project in itself but it still needs a VM to run.
So here is where the second part comes in: the GraalVM produces native binaries from various things, including Clojure code and SCI is simple enough to work with GraalVM.
It's cool how these two pieces of tech combine together to create something greater than the sum of the parts.
However, the elephant in the room (which I also like to ignore as a Clojure enthusiast) is that the start up time of a Java based GUI app is too slow (this is exacerbated even moreso when Clojure is involved)
I'm expecting a GraalVM rejoinder from someone. For anyone who's used GraalVM (particularly with Clojure) - what are the downsides and limitations?
This gist narrowly predates Clojure GraalVM tooling that enables eg Babashka and Clojure usage in cloud FaaS with low cold start latency. And quick startup CLI tools like clj-kondo (a Clojure linter).
It seems there's some WebAssembly related things cooking GraalVM, currently just support for running wasm binaries but will be be interesting to see if eventually we get support for targeting WebAssembly (if WebAssembly one day gets good GC support).
GraalVM has made creating Clojure binaries with quick launch times much more possible. I suggest checking out babashka (Closure bash scripting) as an example and as a means.
Sometimes the trade-off of slow startup vs. having a JIT'ed VM is better, since you get a lot more performance, if you're working w/ long-lived processes.
Have you tried Clojure with the GraalVM native-image? I am curious to what extent native-image can delete the overhead of Clojure and make fast natively compiled binaries.
+1 - I tried using GraalVM for a Clojure(script) + re-frame application recently and it didn't work, changing back to OpenJDK works fine. It's a shame because the times were Graal does work, the start-up time is orders of magnitude faster.
As a side note, GraalVM is quite usable for real world stuff nowadays. Here's an example of running a Clojure web service with Graal that provides JSON endpoints, talks to the database, and does session management: https://github.com/yogthos/graal-web-app-example
The same app can be run on the JVM or compiled statically using Graal. The JVM version takes around a 100 megs of RAM, and has a significant startup time. The Graal version weighs in at 7 megs, and starts up instantly.
This is a good example of where Graalvm's native image is interesting. This is a CLI tool that lets Clojure developers create scripts that are as fast as bash scripts. Clojure may well not be your bag, but stay with me - we're talking about CLI or TUI's written in Java (or a java-based language) that are easy to distribute as statically compiled binaries.
I'm running Clojure code compiled with GraalVM native for AWS Lambda. Cold start times are low and performance is decent enough, even with CE edition. The whole process is reasonably painless through the use of Holy Lambda https://github.com/FieryCod/holy-lambda
Not quite what you were asking for, but I wanted to chip in as another happy Clojure + GraalVM native user.
reply