Skip to content

Conversation

TanayParikh
Copy link
Contributor

@TanayParikh TanayParikh commented Jul 2, 2020

Fixes: https://github.com/dotnet/aspnetcore/issues/23454

Based on the ETL Traces from:
https://github.com/dotnet/aspnetcore/issues/23108
#23095

This issue turned out to already have been resolved from @ToddGrun's PR which brought major performance improvements in this specific area (6.5% less CPU time and 89% less memory allocation).

Baseline before Todd's changes:

Mean Error StdDev Op/s Gen 0 Gen 1 Gen 2 Allocated
100.5 us 0.58 us 0.52 us 9,946.0 0.1221 - - 27.48 KB

After Todd's Changes:

Mean Error StdDev Op/s Gen 0 Gen 1 Gen 2 Allocated
94.28 us 0.897 us 0.795 us 10,607.0 - - - 3.01 KB

With No Sub-stringing At All:

Mean Error StdDev Op/s Gen 0 Gen 1 Gen 2 Allocated
93.12 us 0.222 us 0.185 us 10,739.0 - - - 1.02 KB

Which proves sub-stringing is not an issue.

Added some benchmarks for taghelper parsing so it can help us in potential future investigations.

Benchmarks:

Method Mean Error StdDev Op/s Allocated
'TagHelper Design Time Processing' 2,331.51 us 28.916 us 27.048 us 428.9 985.33 KB
'TagHelper Component Directive Parsing' 90.46 us 0.472 us 0.394 us 11,055.1 3.01 KB

Notes / Attributions:

Fixes: https://github.com/dotnet/aspnetcore/issues/23454

Benchmarks:
|                                  Method |        Mean |     Error |    StdDev |     Op/s | Allocated |
|---------------------------------------- |------------:|----------:|----------:|---------:|----------:|
|      'TagHelper Design Time Processing' | 2,331.51 us | 28.916 us | 27.048 us |    428.9 | 985.33 KB |
| 'TagHelper Component Directive Parsing' |    90.46 us |  0.472 us |  0.394 us | 11,055.1 |   3.01 KB |

Notes / Attributions:
- `BlazorServerTagHelpers` is just a demo file concatonated from the basic `BlazorServer` files
- `RazorDiagnosticJsonConverter` is copied from: https://github.com/dotnet/aspnetcore/blob/b7d9e8cfea97c9a3e6df871666d489556e2a3d0b/src/Shared/RazorShared/RazorDiagnosticJsonConverter.cs
- `TagHelperDescriptorJsonConverter` is copied from: https://github.com/dotnet/aspnetcore-tooling/blob/73c96f1c00b90e0f9d4fdbfb0905376229ceb913/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Serialization/TagHelperDescriptorJsonConverter.cs
- `taghelpers.json` was updated from: https://github.com/dotnet/aspnetcore-tooling/blob/73c96f1c00b90e0f9d4fdbfb0905376229ceb913/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Performance/taghelpers.json
- `ReadTagHelpers` was copied over from https://github.com/dotnet/aspnetcore-tooling/blob/fef50ba62387cb87d34970b4c88290c233361927/src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Performance/ProjectSystem/ProjectSnapshotManagerBenchmarkBase.cs#L83-L93

Fixes: https://github.com/dotnet/aspnetcore/issues/23454
@ghost ghost added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label Jul 2, 2020
Copy link
Contributor

@ajaybhargavb ajaybhargavb left a comment

Choose a reason for hiding this comment

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

Nice!

Which proves sub-stringing is not an issue.

The memory allocation went from 3KB to 1KB which is still good.

@@ -247,8 +247,8 @@ public ComponentDirectiveVisitor(string filePath, IReadOnlyList<TagHelperDescrip
{
// If this is a child content tag helper, we want to add it if it's original type is in scope.
// E.g, if the type name is `Test.MyComponent.ChildContent`, we want to add it if `Test.MyComponent` is in scope.
TrySplitNamespaceAndType(typeName, out var typeNameTextSpan, out var _);
typeName = GetTextSpanContent(typeNameTextSpan, typeName);
TrySplitNamespaceAndType(typeName, out var namespaceTextSpan, out var _);
Copy link
Contributor

Choose a reason for hiding this comment

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

Are these just renames?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@TanayParikh
Copy link
Contributor Author

The memory allocation went from 3KB to 1KB which is still good.

To clarify that 3KB -> 1KB was a hypothetical if we weren't to do substringing at all. We've kept the substringing in place as we need to be able to extract the namespace from a fully qualified name.

The point I was trying to make was that this area has already been optimized substantially (from 27.48KB to 3KB) so any further optimization will have diminishing returns. Note; the ETL's which instigated the issue were from prior to this change.


namespace Microsoft.VisualStudio.LanguageServices.Razor.Serialization
{
internal class RazorDiagnosticJsonConverter : JsonConverter

Choose a reason for hiding this comment

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

You shouldn't need to replicate this. We have a converter in the CodeAnalysis.Workspaces dll already.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed, and updated the Performance.csproj with the file compilation references as we do elsewhere

<None Include="MSN.cshtml" CopyToOutputDirectory="PreserveNewest" />
<None Include="taghelpers.json" CopyToOutputDirectory="PreserveNewest" />
<None Include="BlazorServerTagHelpers.razor" CopyToOutputDirectory="PreserveNewest" />
<Compile Include="$(SharedSourceRoot)RazorShared\TagHelperDescriptorJsonConverter.cs">
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@TanayParikh TanayParikh requested a review from NTaylorMullen July 6, 2020 18:19
@TanayParikh TanayParikh merged commit 1c2a0f4 into master Jul 6, 2020
@TanayParikh TanayParikh deleted the taparik/taghelper_benchmarks branch July 6, 2020 23:32
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
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Resolving TagHelper scopes is very expensive due to substringing typenames
4 participants