tweag / nickel

Better configuration for less
https://nickel-lang.org/
MIT License
2.37k stars 89 forks source link

Specialized pattern compilation for enum tags #1846

Closed yannham closed 6 months ago

yannham commented 6 months ago

The recent introduction of full pattern matching incurred a big performance regression for very large enum contracts (initially reported by @Quantum64).

Indeed, previously enum-only pattern matching would directly index into a hashmap of the branches of the pattern - where the key is the enum tag which is the pattern associated with the branch -, giving amortized constant time.

The more powerful and generic pattern matching introduced later instead compiles each pattern to a (potentially complex) boolean check. This is necessary in general, but for match statements that are just composed of bare enum tags, this trades a constant time operation for a linear one (in the number of branches). This has shown important regressions on specific code bases making heavy usage of very large enum contracts.

This commit specializes the compilation of match expressions when all the patterns are enum tags to recover the old behavior. We just reuse the unary operator %match%, which was precisely used to implement the old pattern matching, and was just standing there unused since the introduction of the new match expression compilation.

This recovers the same performance as 1.4.1, tested locally, on the offending codebases.

Future work

We could actually extend this optimization, without a lot of effort, to match expressions where patterns are enums in general (and not only enum tags). We would index in the hashmap by enum tag, and only then perform the potentital remaining cheap checks to distinguish bewteen 'Foo and 'Foo x. This is left for future work.