TIL that when invoking a JVM without JIT and without OnStackReplacement, loops are similarly slow (even slower!) as bb:
$ clj -J-XX:-UseOnStackReplacement -J-Xint
Clojure 1.12.1
user=> (time (loop [i 0 j 10000000] (if (zero? j) i (recur (inc i) (dec j)))))
"Elapsed time: 493.458333 msecs"
10000000
$ rlwrap bb
user=> (time (loop [i 0 j 10000000] (if (zero? j) i (recur (inc i) (dec j)))))
"Elapsed time: 364.688709 msecs"
10000000not sure if its worth to compare without the compilation overhead in the JVM but then it may not be shaving off much in the grand scheme
I guess compilation overhead can be measured by turning this into a function and then running it
user=> (doit)
"Elapsed time: 496.091375 msecs"
10000000
user=> (doit)
"Elapsed time: 495.746084 msecs"
time already runs outside of the compilation, it measures at runtimeJust to put this on your radar: https://cr.openjdk.org/~jiangli/hermetic_java.pdf
This seems to be actively being investigated
https://mail.openjdk.org/pipermail/leyden-dev/2025-June/thread.html
So it would hypothetically be a path to a self contained exe that is different than native-image. Downside/Interesting Problem to solve is that it seems like it is to be a target for jlink. jlink only likes it when everything is a module.
Clojure and everything involved can go on the module path instead of the class path with just a --add-modules ALL-MODULE-PATH but no clojure library will have a module descriptor. Obviously one could begin the scutwork of adding them, but thats not worth it unless both hermetic java becomes real and has benefits over native image that people end up valuing
(doodles from today https://gist.github.com/bowbahdoe/c83c756b12a6756e4f8faf23ea2877ba)
Would this also have good startup time like native-image (below 25ms or so let's say?)
good question - obviously packing things into one file is gonna affect some aspect of performance, but i think with nothing else done its probably going to be in line with regular java. That being said, the whole leyden thing is adding mechanisms for improving startup. Im sure that a finished version of this will have some ability to interact with the CDS stuff they've already done and whatever comes next
so my best guess is that if its possible to get startup low enough its going to be through doing training runs + recording profile data. So not too dissimilar to native-image (where you sometimes run an agent to capture reflection/serialization/etc.)
This test should give hints https://github.com/jarppe/clojure-app-startup-time-test
> "The Leyden CDS seems really promising as it reduces the startup time from 7 sec to 1 sec.
> The GraalVM image is really fast to start, but also most difficult to produce. This simple application does not have any dependencies (other than Clojure standard lib) it's pretty simple, but when you add dependencies it gets more complicated."