How to provide a fresh, blank Clojure evaluation environment to sub-scripts?

Ash Ra Template uses ShimDandy to provide a completely isolated Clojure evaluation environment to .art templates. On contemporary fast CPUs, from (vivid.art/render) it takes say 1 second before actual template evaluation begins; this time is wholly accounted for by ShimDandy doing its thing. Have 10 templates? Then rendering will take 10 seconds just for setup. As this less-than-ideal state of affairs represents ART version 0.4.0, let’s code-name that release “Mood Killer.”

Ideally, ART would be technically capable of rendering 1000s of templates per second on the same hardware, measuring just render setup and tear-down time. Now that we are in serious planning for the next version of ART (0.5.0), we seek performance improvements.

Specifically, templates will have the option to be evaluated within what appears to them as a completely initialized Clojure environment, with no namespace pollution. Is there a faster way than ShimDandy? Let’s see if we can give this next release the codename “Dream Machine!”

Well, most of the deep dive into Clojure slow start time that I’ve seen indicate the slowness is mostly in the runtime initialization. Loading all.classes, intializing vars, etc.

So it seems ShimDandy suffers similarly.

My thought is, can you isolate at a lower level, so template generation use the same run-time, and still somehow avoid clashing between themselves?

Another thought is, can you compile ART with GraalVM?

Another thought is, can you use https://github.com/borkdude/sci for isolated template generation. Would start faster, but might run slower so would need to measure.

And my last thought is, instead of using Shim Dandy, if you spawned child Clojure processes, those could be parallelized (or maybe ShimDandy itself can). So 10 templates means 10 child process each taking 1 second, thus all 10 complete in 1 second.

Another important question to ask: what would be the trade off in not isolating the script runtime?

The template libraries I’ve used don’t bother to isolate scripting.

Hey, thanks for these gear-turning ideas.

Perhaps Clojure internals provide a mechanism for (re-)initializing, and combined with some class-loader gung-fu it might be possible to wire together a system that provides an environment that can be scribbled on by a template evaluation and then quickly reset back to an initialized state ready for the next template (undo the scribbling), a process repeated for each successive template. Utilizing either public/sanctioned APIs or as a jerry-rigged prototype until I can convince upstream. Since it appears Clojure start-up time is responsible, a price of the first hit isn’t free would be acceptable if all ensuing templates could be rapidly rendered. I’ll research it. And if anyone can go into deeper details…?

GraalVM

ART is meant to be a composable library; any use of GraalVM is up to the wielder.

sci

Ah, swap the Clojure implementation, well, we are committed to developing ART to target Clojure straight-up, because that is how we use it internally. At least for now…

parallelized

A capital idea; I foresee a user-selectable option.
/me adds this item to the idea queue

Right, this we have decided to make user-selectable in the next release. It might matter, it might not; only the user can really say.

One such template library that doesn’t isolate scripting is weavejester’s comb. It’s basically pass-through, and that is fine for some of our use-cases.

I’d suggest you look at sci a bit more carefully. It’s an interesting little thing, because while yes it is technically a different implementation, it delegates everything back to the Clojure JVM implementation.

It might not fit, but it’s surprisingly polyvalent. It depends though how much of Clojure you expect templates to leverage. If you want templates to be able to do everything under the sun, it won’t fit. But if templates are meant to only pull data in a select few ways and then only do pure data transforms on those, it could be a good option.

1 Like