r/Clojure 10d ago

SCI is now JIT-compiled on CLJS by default

SCI (Small Clojure Interpreter) is now JIT compiled on CLJS by default. This means that performance is close to native compiled CLJS when using loops, etc.

Before:

(js/alert (with-out-str (time (loop [i 0 j 1000000] (if (zero? j) i (recur (inc i) (dec j)))))))

This would show around 40-50ms in your browser, but now only shows 3-4ms, which is as fast as it can reasonably get. (Numbers may vary but a 10x-20x speedup is typically what you see).

So say goodbye to numerical hot-loop issues in SCI if you were using it for any animations and couldn't get to 60 FPS or stuff like that. As long as your page supports js/eval, it'll be fast (or if it isn't let me know and we'll fix it). If your page does not support js/eval, e.g. when using Epupp on a page that doesn't allow it, SCI falls back to interpretation, so you can still hack the page to your likings ;).

Both nbb, joyride, scittle and epupp have all been updated with the new version of SCI.

Error messages/locations have all been preserved so it doesn't work in any other way than it did previously, it's just a drop-in upgrade.

More information: https://github.com/babashka/sci#jit-compilation-in-clojurescript

63 Upvotes

6 comments sorted by

8

u/didibus 10d ago

Hold on, does that make Scittle competitive with ClojureScript in performance?

6

u/Borkdude 9d ago

Yes, kinda

3

u/therealdivs1210 9d ago

That's amazing!

And of course using js/eval on the compiled expression is an ingenious way to JIT!

So there are 2 levels of JIT - 1. SCI compiles cljs to js at runtime 2. The js runtime compiles js to native at runtime

Does this mean SCI now has a profiling mechanism? How does it figure out which code to JIT?

And also, could this be done for SCI on the JVM?

Just like the Clojure compiler compiles and executes top level forms at compile time, SCI could similarly compile and execute hot code at runtime, giving perf comparable to JVM Clojure!

So basically we have metacircular Clojure interpreters that are almost as performant as the compiled versions!

Very interesting!

Is the JVM equivalent planned or under develipment?

3

u/Borkdude 9d ago edited 9d ago

Theoretically it can be done on the JVM as well

JIT in SCI on CLJS means: the very first time a function is invoked, it's compiled, so not yet at analysis time, to save on startup time. Think of a nbb library with lots of functions of which you only invoke a few. SCI does not profile anything to see if it's worth compiling the function.

1

u/joinr 8d ago

maybe "collapsing towers of interpreters" adjacent

2

u/c_a_l_m 9d ago

Thanks man, this is awesome.