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

Improve DFA matcher builder startup perf with many constraints #46323

Merged
merged 7 commits into from
Jan 31, 2023

Conversation

JamesNK
Copy link
Member

@JamesNK JamesNK commented Jan 30, 2023

Fixes #46154

  • Adds a cache to the matcher builder to reuse constraints marked as cachable.
  • RegexRouteConstraint creates its Regex instance lazily. Still important in situations where the web app has many non-duplicate regexes.

@JamesNK JamesNK added the area-web-frameworks *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels label Jan 30, 2023
@ghost ghost added the area-runtime label Jan 30, 2023
@JamesNK
Copy link
Member Author

JamesNK commented Jan 30, 2023

Numbers:

Main (interpreted regex)

| Method | RegexSame |     Mean |     Error |    StdDev |  Op/s |   Gen 0 |  Gen 1 | Gen 2 | Allocated |
|------- |---------- |---------:|----------:|----------:|------:|--------:|-------:|------:|----------:|
|  Build |     False | 6.739 ms | 0.0801 ms | 0.0710 ms | 148.4 | 15.6250 |      - |     - |      7 MB |
|  Build |      True | 6.247 ms | 0.0859 ms | 0.0804 ms | 160.1 | 15.6250 | 7.8125 |     - |      7 MB |

Main (compiled regex)

| Method | RegexSame |     Mean |    Error |   StdDev |  Op/s |   Gen 0 |   Gen 1 | Gen 2 | Allocated |
|------- |---------- |---------:|---------:|---------:|------:|--------:|--------:|------:|----------:|
|  Build |     False | 24.85 ms | 0.485 ms | 0.476 ms | 40.24 | 62.5000 | 31.2500 |     - |     28 MB |
|  Build |      True | 26.00 ms | 0.284 ms | 0.251 ms | 38.47 | 62.5000 | 31.2500 |     - |     26 MB |

PR

| Method | RegexSame |     Mean |     Error |    StdDev |  Op/s |  Gen 0 |  Gen 1 | Gen 2 | Allocated |
|------- |---------- |---------:|----------:|----------:|------:|-------:|-------:|------:|----------:|
|  Build |     False | 1.521 ms | 0.0238 ms | 0.0211 ms | 657.2 | 5.8594 | 1.9531 |     - |      2 MB |
|  Build |      True | 1.235 ms | 0.0157 ms | 0.0139 ms | 809.5 | 3.9063 |      - |     - |      1 MB |

@JamesNK JamesNK added area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates Perf and removed area-runtime area-web-frameworks *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels labels Jan 30, 2023
@@ -1,8 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#nullable disable
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: Nothing has functionally changed in this class. I made changes to it (enable nullable, split up methods) intending to use it, but found I didn't need to. I left the changes here as they're all positive.

{
// Create regex instance lazily to avoid compiling regexes at app startup. Delay creation until constraint is first evaluation.
// This is not thread safe. No side effect but multiple instances of a regex instance could be created from a burst of requests.
_constraint ??= new Regex(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess if a constraint is evaluated once, it's likely to be hit an arbitrary number of times over the life of the app?

If that wasn't the case one could imagine lazily instantiating as interpreted first, then counting until a threshold and swapping for compiled.

Copy link
Member

@davidfowl davidfowl Jan 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is similar to what DI does, but it could be something we do after this change. We would need to make sure this happened in a place that could properly measure the "hit count". I'm not sure where that is.

Copy link
Member

@mgravell mgravell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good; one question

src/Http/Routing/src/Matching/DfaMatcherBuilder.cs Outdated Show resolved Hide resolved
Copy link
Member

@davidfowl davidfowl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very clever

@JamesNK JamesNK added the blog-candidate Consider mentioning this in the release blog post label Jan 30, 2023
@ghost
Copy link

ghost commented Jan 30, 2023

@JamesNK, this change will be considered for inclusion in the blog post for the release it'll ship in. Nice work!

Please ensure that the original comment in this thread contains a clear explanation of what the change does, why it's important (what problem does it solve?), and, if relevant, include things like code samples and/or performance numbers.

This content may not be exactly what goes into the blog post, but it will help the team putting together the announcement.

Thanks!

@JamesNK JamesNK changed the title Improve DFA matcher builder startup performance with many constraints Improve DFA matcher builder startup perf with many constraints Jan 31, 2023
@JamesNK JamesNK merged commit eab7cf5 into main Jan 31, 2023
@JamesNK JamesNK deleted the jamesnk/regexroute-startupperf branch January 31, 2023 01:06
@ghost ghost added this to the 8.0-preview1 milestone Jan 31, 2023
@dougbu
Copy link
Member

dougbu commented Jan 31, 2023

@JamesNK sorry this missed branching for preview1 by just a few minutes. If you want it in that release, please do the needful.

@JamesNK
Copy link
Member Author

JamesNK commented Jan 31, 2023

Waiting for preview 2 is fine. Thanks for the heads up though.

@JamesNK JamesNK modified the milestones: 8.0-preview1, 8.0-preview2 Jan 31, 2023
Copy link
Member

@javiercn javiercn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great @JamesNK

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates blog-candidate Consider mentioning this in the release blog post Perf
Projects
None yet
Development

Successfully merging this pull request may close these issues.

RegexRouteConstraint should use Compiled Regex
6 participants