matcher-combinators

oyakushev 2025-04-02T22:50:24.091999Z

Hi! I've noticed this today – apparently, matcher-combinators.matchers/embeds with a sequential expected uses match-all-permutations under the hood. In the case of a mismatch, the permutations generated for expected do explode both the running time and allocation pressure. Example:

(-/time (is (match? (matcher-combinators.matchers/embeds [0 1 2 3 4 5 6 7 8 100]) (range 30))))
=> Time per call: 22.96 s   Alloc per call: 64,660,456,416b
Am I wrong to assume that a simple matches-in-any-order? predicate would be sufficient in this case? Is there a point to generating all permutations if after that the preds are looked in the actual separately one by one regardless of order?

Phillip Mates 2025-04-03T18:36:34.458209Z

hey, thanks for raising this. So the library tries to find the smallest possible mismatch in these cases, which is more work than just looking for a match or not; resulting in really poor performance in certain cases. I was considering adding a way to, via a config/optional arg, toggle whether to do the smallest-possible-mismatch work or not. Never got around to it and am not really programming much these days There is some discussion about this issue in https://github.com/nubank/matcher-combinators/issues/221#issuecomment-2019934400 and https://github.com/nubank/matcher-combinators/issues/106

oyakushev 2025-04-03T18:40:42.891249Z

Thank you! I see now that (is (match? (mc/in-any-order [odd? even? 1]) [1 2 3])) is indeed tricky and requires testing all permutations to be sound.