-
Notifications
You must be signed in to change notification settings - Fork 231
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
Performance: Token Type Utility Analyzer: Avoid allocations #6785
Performance: Token Type Utility Analyzer: Avoid allocations #6785
Conversation
analyzers/src/SonarAnalyzer.Common/Rules/Utilities/TokenTypeAnalyzerBase.cs
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.
Do we even need the inner class here at all? I think getting rid of it, makes the whole thing much easier to understand and extend.
analyzers/src/SonarAnalyzer.Common/Rules/Utilities/TokenTypeAnalyzerBase.cs
Outdated
Show resolved
Hide resolved
analyzers/src/SonarAnalyzer.Common/Rules/Utilities/TokenTypeAnalyzerBase.cs
Outdated
Show resolved
Hide resolved
analyzers/src/SonarAnalyzer.Common/Rules/Utilities/TokenTypeAnalyzerBase.cs
Outdated
Show resolved
Hide resolved
analyzers/src/SonarAnalyzer.Common/Rules/Utilities/TokenTypeAnalyzerBase.cs
Outdated
Show resolved
Hide resolved
analyzers/src/SonarAnalyzer.Common/Rules/Utilities/TokenTypeAnalyzerBase.cs
Outdated
Show resolved
Hide resolved
@pavel-mikula-sonarsource can you please have a second look and merge if appropriate? The reasoning for the change is given in the PR description. |
@martin-strecker-sonarsource can you run the full analysis for Akka.Net and Lucene.Net projects to measure the impact? |
This PR is more of a refactoring and a precondition to improving The results are:
Runtime
A second run of Akka for the PR gave a runtime of 47s (slightly better than the master) with 7,688.16615 MB allocations.
|
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.
LGTM, that's a very nice change!
analyzers/src/SonarAnalyzer.Common/Rules/Utilities/TokenTypeAnalyzerBase.cs
Outdated
Show resolved
Hide resolved
analyzers/src/SonarAnalyzer.Common/Rules/Utilities/TokenTypeAnalyzerBase.cs
Outdated
Show resolved
Hide resolved
analyzers/src/SonarAnalyzer.Common/Rules/Utilities/TokenTypeAnalyzerBase.cs
Outdated
Show resolved
Hide resolved
Please run it without AnalyzerRunner to have more realistic view? |
There shouldn't be any difference in runtime as the work done is the same as before. We avoid allocations in the hot path, which just reduces the pressure on the garbage collector. The analyzer runner also measures allocations, and we see some reduction there (the allocation measure doesn't fluctuate as much as the runtime does, so the ~10% reduction there is real). MyClass(List<String> list) // constructor Causes two semantic model calls for each identifier token:
We can easily avoid these in this case by checking the parent:
That alone saves 2x8 semantic model calls. |
While the memory footprint is good to know too, the purpose is to have realistic data in terms of user experience. |
SonarCloud Quality Gate failed. |
Kudos, SonarCloud Quality Gate passed! |
I looked into the code colorization on peach for some projects. I could not find anything unusual. |
Peach deployment failed and this was not deployed on Peach yet |
The current implementation of the
TokenTypeAnalyzerBase
has the following problems:This PR changes how the TokenClassifierBase operates.
Instead of one new TokenClassifierBase per Token, the TokenClassifierBase is now created once per document. The token is passed to
ClassifyToken
.ClassifyToken
was changedTokenInfo
into the collecting listTokenInfo
to the callerThe trivia handling was extracted into
TriviaClassifierBase
to allowTokenClassifierBase.ClassifyToken()
to return a singleTokenInfo
instead of a list. The trivia is now processed before (LeadingTrivia) and after (TrailingTrivia) the token and so the ordering is guaranteed.The calculation of the
TokenInfo.TextRange
was simplified, and theGetSubText
call instring.IsNullOrWhiteSpace(token.SyntaxTree.GetText().GetSubText(span).ToString())
check could be removed.This PR is the groundwork needed to tackle
ClassifyIdentifier
next, which can be improved by avoiding querying the semantic model in many cases (e.g., an identifier in a parameter syntax is known to be an IParameterSymbol and there is no need to look up the symbol).