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.
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.