Skip to content

Reduce excessive allocations in BannedSymbols analyzer. #6568

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

Merged
merged 9 commits into from
Apr 4, 2023

Conversation

CyrusNajmabadi
Copy link
Member

@CyrusNajmabadi CyrusNajmabadi commented Apr 4, 2023

The core problem here is that hte BannedSymbols analyzer starts with a top down walk that attempts to find the corresponding ISymbol for a symbol in the symbol tree. This can be quite expensive as the compiler has to realize all the symbols downwards (in order to look up those names), including walking into symbols that might be enormous (consider large namespaces, or types with 10s of thousands of members).

This PR flips the general idea of hte banned-analyzer around. Instead of upfront computing the list of banned symbols, we instead look for the names (and container names) specified in BannedSymbols.txt. Then, as we're analyzing, only if we hit a real symbol with those names, do we attempt to them go map the banned-symbol line back to actual ISymbols, which we then compare the current symbol being analyzed.

This means, if the code being analyzed never actually refers to the potential bad symbol, we don't pay any price looking it up.

Addresses 600 MB of allocations in a simple typing/lightbulb scenario:

image

@CyrusNajmabadi CyrusNajmabadi requested a review from a team as a code owner April 4, 2023 20:13
return ParseDeclaredId(id, ref index);
}

private static (string ParentName, string SymbolName)? ParseDeclaredId(string id, ref int index)
Copy link
Member Author

Choose a reason for hiding this comment

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

{
foreach (var bannedFileEntry in entries)
{
foreach (var bannedSymbol in bannedFileEntry.Symbols)
Copy link
Member Author

Choose a reason for hiding this comment

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

we defer creating the 'Symbols' for an entry until the point it is actually needed. this is hte majority of hte perf in here.

@@ -325,6 +361,9 @@ public BanFileEntry(string text, TextSpan span, SourceText sourceText, string pa
Span = span;
SourceText = sourceText;
Path = path;

_lazySymbols = new Lazy<ImmutableArray<ISymbol>>(
() => DocumentationCommentId.GetSymbolsForDeclarationId(DeclarationId, compilation));
Copy link
Member Author

Choose a reason for hiding this comment

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

this is calling into the real (expensive) roslyn API again to find the symbols.

@RikkiGibson RikkiGibson self-assigned this Apr 4, 2023
string parentName = "";

// process dotted names
while (true)
Copy link
Member Author

Choose a reason for hiding this comment

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

honestly, this could be a lot better. HOwever, i don't care much simple the logic is:

  1. trivial
  2. the same as the version in Roslyn
  3. there are usually only a couple hundred banned API items. So the allocations here are not a concern and not something to worry about. The thing we care about fixing is avoiding hte massively expensive symbol walk.

@codecov
Copy link

codecov bot commented Apr 4, 2023

Codecov Report

Merging #6568 (b994b17) into main (916b9a6) will decrease coverage by 0.01%.
The diff coverage is 90.09%.

❗ Current head b994b17 differs from pull request most recent head 39a5df0. Consider uploading reports for the commit 39a5df0 to get more accurate results

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6568      +/-   ##
==========================================
- Coverage   96.43%   96.43%   -0.01%     
==========================================
  Files        1372     1373       +1     
  Lines      320265   320341      +76     
  Branches    10293    10309      +16     
==========================================
+ Hits       308844   308908      +64     
- Misses       8967     8977      +10     
- Partials     2454     2456       +2     

@ToddGrun
Copy link

ToddGrun commented Apr 4, 2023

LGTM, signing off for what it's worth.

Copy link

@ToddGrun ToddGrun left a comment

Choose a reason for hiding this comment

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

:shipit:

@CyrusNajmabadi CyrusNajmabadi enabled auto-merge April 4, 2023 21:50
@CyrusNajmabadi CyrusNajmabadi merged commit 7e98f62 into main Apr 4, 2023
@CyrusNajmabadi CyrusNajmabadi deleted the bannedApiWork branch April 4, 2023 22:21
@github-actions github-actions bot added this to the vNext milestone Apr 4, 2023
mavasani added a commit to dotnet/roslyn that referenced this pull request Apr 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants