Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Specialized pattern compilation for enum tags #1846

Merged
merged 1 commit into from
Mar 11, 2024

Conversation

yannham
Copy link
Member

@yannham yannham commented Mar 11, 2024

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 performance
regression for very large enum contracts.

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) booleanc check. This is
necessary in general, but for match statements that are just composed of
bare enum tags, this trade a constant time operation for a linear (in
the number of branches). This shown important regressions on some code
bases making heavy usage of very large enum types/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.
@yannham yannham requested review from jneem and vkleen March 11, 2024 14:45
@github-actions github-actions bot temporarily deployed to pull request March 11, 2024 14:49 Inactive
@yannham yannham enabled auto-merge March 11, 2024 15:04
@yannham yannham added this pull request to the merge queue Mar 11, 2024
Merged via the queue into master with commit c3e180f Mar 11, 2024
5 checks passed
@yannham yannham deleted the fix/enum-contracts-perf-regression branch March 11, 2024 15:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants