Last week @jimmy and I encountered a situation where a Meander query was several milliseconds slower than some hand jammed Clojure — which is expected and no surprise — and while normally this would be no issue, in this case performance was critical and, so, we went with the vanilla Clojure.
Since it was so close, we took a moment to macroexpand the query, delete all the type checks, and see how the performance fared and, indeed, in doing so we were able to close the gap to just a couple milliseconds. We also made some other tweaks and were able to get the expanded code within just one millisecond. This is something I’ve been aware of and came up in a previous discussion with @wxitb2017 in the past year.
I’ve talked about adding an unsafe flag and, now, I think it’s time to act on that because, in this case, we made a decision to turn down Meander because its performance was unacceptable.
At the moment I’m working on this (its a surprisingly simple patch) to disable some of the basic type checks such that it will work similarly to destructure
. I suspect we will want some control over. For example, we may want type checks disabled but bounds checks to remain, vice versa, or simply no checks at all. Currently, what I have and plan to submit for review looks like
^::m/unsafe
(m/find x ,,,)
which will disable both type checks and bounds checks. In the case of disabling bounds checks, this causes the compiler emit (nth target index not-found)
instead of (nth target index)
. Likely, the patch will include the knobs ::m/omit-type-checks
and ::m/omit-bounds-checks
with ::m/unsafe
expanding to true
in both cases.👏
The omissions will happen at the lowest level of the compiler e.g. where Clojure code is generated which means the generated code will have the same structure is safe code (excluding the omissions).
To avoid potential confusion, this will not affect something like (m/pred map? ,,,)
.