https://github.com/metosin/malli/issues/1269 heads up: performance problems
or perhaps just users getting used to the new performance tradeoffs 🙂
it's binding
The easiest fix without causing a performance regression is adding a context argument and pass it everywhere, but it'll be a pain
I don't know how to do it without breaking users who implemented their own validator, too
a mitigation is using a hack which slightly improves bindings' performance
https://github.com/bsless/prrr/blob/master/src/bsless/prrr.clj#L193 That's the entire diff
The algorithm itself is much more expensive up-front since it eagerly realizes all schemas recursively. binding is probably an expensive component of that. We could distribute the cost to runtime by treating all refs as lazy, which the tradeoff that memory will increase at validation time again (but now to a limit).
You'd do this by making lazy => true here: https://github.com/metosin/malli/commit/d3d09fb0ccfd79ba8f254e4b41baad11a3062cbd#diff-c10cf1bd7f29baf493dfd1fb727c955f2bf09a256cdc7ff690343b5940f14940R1995
It would also be really nice if we had a context argument, I'm also not sure how to do that without breaking third party schemas.
Perhaps a Schema2 protocol that adds context args, and the default dispatch falls back to bindings?
Also, the algorithm could be much smarter about reusing validators for identical schemas. for example (validator [:schema {:registry {::Foo :int}} [:tuple ::Foo ::Foo]) will walk ::Foo twice and create two validators. I described the worst case in my clojurists together proposal https://gist.github.com/frenchy64/2de3a8405a76fdeec9bc0ef7ac5ceefe
I commented on the https://github.com/metosin/malli/issues/1269 with a potential fix we can try.
The fix seems to work, I put it into review: https://github.com/metosin/malli/pull/1270
@danstone I think this ^ will help with metabase memory usage on startup too if you're still stuck on that. With the caveat that memory may grow until all validators are lazily realized.