I’m super excited to announce the latest 1.3 release of purs-backend-es, an alternative backend for modern ES code based on the purescript-backend-optimizer pipeline. This release contains a host of ES-specific improvements to bring it up to parity with the current JS backend (and beyond).
The JS backend employs a few optimizations specific to Effect and ST for writing fairly low-level code which generates more performant imperative JS. Previous versions of purs-backend-es did not support these optimizations, making performance potentially regress in some cases.
- Loop inlining (
foreachE,forE,whileE, etc). By inlining loops and their bodies, we can avoid thunk allocations forEffecton each iteration. - STRef unboxing, which can eliminate the
{value: ...}box for references in some specific cases.
purs-backend-es can now perform these optimizations, but also a lot more!
- General
Refunboxing, which applies to both Effect and ST. - Inlining of
STArrayandSTObjectoperations (array push, object update, etc). - More robust and reliable ST transformations (due to the powerful inliner in
purs-backend-optimizer).
As an anecdote, several years ago I wrote halogen-vdom with the goal of writing as much in PureScript as possible while still retaining production quality performance. I was fairly successful with about 95% of the code being written in PureScript, however, the core diffing algorithms were written in FFI for performance. I can confidently say that is no longer necessary! Compare the original FFI, and code that can be generated by purs-backend-es:
This is equivalent, and likely faster given that for/of iteration over Object.keys is more performant than for/in iteration nowadays. My hope and goal is that “write FFI code for performance” should not be a thing.