-
Notifications
You must be signed in to change notification settings - Fork 191
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 performance of DefaultRazorTagHelperContextDiscoveryPhase
#10602
Improve performance of DefaultRazorTagHelperContextDiscoveryPhase
#10602
Conversation
We can avoid sifting through all tag helpers and performing string comparisons by storing tag helpers them in a dictionary keyed by assembly name.
This is still in need of reviews from @dotnet/razor-compiler |
...osoft.CodeAnalysis.Razor.Compiler/src/Language/DefaultRazorTagHelperContextDiscoveryPhase.cs
Outdated
Show resolved
Hide resolved
src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/ReadOnlyListExtensions.cs
Outdated
Show resolved
Hide resolved
src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/ReadOnlyListExtensions.cs
Outdated
Show resolved
Hide resolved
src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/ReadOnlyListExtensions.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I don't love the nonComponentTagHelper
prefixes in the visitor, as it confused me a bit at first that we were explicitly differentiating but not within the type, but I get where you're coming from.
Seems like another case of 'we need a better name than 'tag helper'' that we were talking about a while back :/
legacyTagHelper, mvcTagHelper, cshtmlTagHelper...? |
Y'all are free to consider this discussion outside of my pull request. I'm not going to name this here. 😄 |
There are two visitors -- one that applies to "components" and one that applies to "tag helpers". Since both are really built on "tag helpers", it seemed to me that the real distinction is whether a tag helper represents a component or not. If you have better names, I'm definitely happy to use them. |
This is some follow-up work after a discussion with @ToddGrun. Previously, @ToddGrun made a change to use pooled lists within the
DirectiveVisistors
used byDefaultRazorTagHelperContextDiscoveryPhase
. However, looking at further traces, there is still a ton of CPU-bound work. Notably, there are loads of string comparisons that happen over and over to compare strings for assembly names. To address this, I've made the following changes:DirectiveVisitors
themselves are pooled and they own their data structures.TagHelperDirectiveVisitor
has been updated to store aDictionary<string, List<TagHelperDescriptor>>
rather than a flatList<TagHelperDescriptor>
. This is used to index tag helpers by assembly name, which greatly reduces the number of string comparisons. TheList<TagHelperDescriptor>
held stored in the dictionary are pooled to avoid extra allocations of tag helpers per assembly.