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

Filter trees to only those containing global-usings or attributes prior to analyzing them. #62444

Merged
merged 10 commits into from
Jul 7, 2022

Conversation

CyrusNajmabadi
Copy link
Member

This cuts down on the sizes of tables enormously, by only have the tables be the size of those much smaller sets versus the entire number of trees we have (which could be in the thousands).

This takes us from 3.8s to 1.9s (a 50%) improvement, and from 2.2GB memory:

image

To 0.92GB (a 58% savings):

image

Assert.Equal(IncrementalStepRunReason.Removed, runResult.TrackedSteps["result_ForAttribute"].Single().Outputs.Single().Reason);
Assert.False(runResult.TrackedSteps.ContainsKey("compilationUnit_ForAttribute"));
Assert.False(runResult.TrackedSteps.ContainsKey("compilationUnitAndGlobalAliases_ForAttribute"));
Assert.False(runResult.TrackedSteps.ContainsKey("result_ForAttribute"));
Copy link
Member Author

Choose a reason for hiding this comment

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

@chsienki i need help here. for some reason the incremental generator is not tracking any steps here when the list filters down to the empty set. Can you help me debug through this to find out why that is?

Copy link
Contributor

Choose a reason for hiding this comment

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

I looked at this, and I see whats going on. I think I have a fix for it, but its a little involved. I think we should open an issue here, and take the fix as a separate PR.

Copy link
Member Author

Choose a reason for hiding this comment

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

Will do.

Copy link
Member Author

Choose a reason for hiding this comment

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

Tracked with #62468

return syntaxHelper.ContainsGlobalAliases(root, cancellationToken);
})
.Select((tree, cancellationToken) => getGlobalAliasesInCompilationUnit(syntaxHelper, tree.GetRoot(cancellationToken)))
.WithTrackingName("individualFileGlobalAliases_ForAttribute");
Copy link
Member Author

Choose a reason for hiding this comment

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

huge savings, as most files do not have global aliases.

// Don't bother looking in trees that don't even have attributes in them.
var root = tree.GetRoot(cancellationToken);
return ContainsAttributeList(root.Green, syntaxHelper.AttributeListKind);
})
Copy link
Member Author

Choose a reason for hiding this comment

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

large savings when attributes are rare in a project.

@@ -79,7 +79,6 @@ public NodeStateTable<TOutput> UpdateStateTable(DriverStateTable.Builder builder
}
}

Debug.Assert(newTable.Count == totalEntryItemCount);
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 assert was just not safe. in a transform we can be transforming 1:N (where N is 0, 1 or >2). So we can't make a determination about how many items teh final count is. It's till good to prime the number of items based on what we previously saw, for the 1:1 case though.

@CyrusNajmabadi CyrusNajmabadi requested a review from jcouv July 7, 2022 14:41
@CyrusNajmabadi
Copy link
Member Author

@jcouv ptal. tahnks!

@@ -60,5 +63,7 @@ internal abstract class AbstractSyntaxHelper : ISyntaxHelper

public abstract void AddAliases(GreenNode node, ArrayBuilder<(string aliasName, string symbolName)> aliases, bool global);
public abstract void AddAliases(CompilationOptions options, ArrayBuilder<(string aliasName, string symbolName)> aliases);

public abstract bool ContainsGlobalAliases(SyntaxNode root, CancellationToken cancellationToken);
Copy link
Contributor

Choose a reason for hiding this comment

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

Not part of your change, but wondering why we have both interface and abstract class flavors of this? Looks like the abstract class doesn't really add functionality here?

Copy link
Member Author

Choose a reason for hiding this comment

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

So this is a pattern i follow when doing thigns with C# and VB. If you don't do this, then the VB side is more obnoxious as every impl has to include the interface information. the abstract approach means that both C# and VB just need to override.

Copy link
Contributor

Choose a reason for hiding this comment

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

One developer's awesome feature that makes it clear when a method implements an interface method is another developer's annoying requirement to make me restate things that can be implicit ;)

Copy link
Member Author

@CyrusNajmabadi CyrusNajmabadi left a comment

Choose a reason for hiding this comment

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

comment

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

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

LGTM Thanks (iteration 10)

@jcouv jcouv self-assigned this Jul 7, 2022
@CyrusNajmabadi CyrusNajmabadi enabled auto-merge (squash) July 7, 2022 18:39
@CyrusNajmabadi CyrusNajmabadi merged commit 060025d into dotnet:main Jul 7, 2022
@ghost ghost added this to the Next milestone Jul 7, 2022
@CyrusNajmabadi CyrusNajmabadi deleted the filterSteps branch July 7, 2022 19:55
333fred added a commit to 333fred/roslyn that referenced this pull request Jul 7, 2022
* upstream/main: (62 commits)
  Prevent assert from being hit (dotnet#62366)
  Don't offer '??=' for pointer types (dotnet#62476)
  Integrate generator times into /reportAnalyzer (dotnet#61661)
  Switch to a callback for cleaning up resources instead of passing in an explicit IDisposable. (dotnet#62373)
  Filter trees to only those containing global-usings or attributes prior to analyzing them. (dotnet#62444)
  Update PublishData.json
  Complete 'file' support for `SyntaxGenerator` (dotnet#62413)
  Apply changes directly to text buffer (dotnet#62337)
  Remove LangVer check from extended nameof binding (dotnet#62339)
  Fixed shared project file error (dotnet#62466)
  Handle new error codes
  Use MSBuid generated property for package path
  Exclude BCL libraries from Roslyn vsix
  Bump the integration test timeouts a bit
  Skip the balanced switch dispatch optimization for patterns on floating-point inputs (dotnet#62322)
  Test helpers shouldn't escape quotes by default (dotnet#62321)
  Reuse prior TableEntry values in the increment NodeTable builder if possible. (dotnet#62320)
  Install 3.1 runtime for SBOM tool
  Generate VS SBOM during official build.
  Minor refactoring in 'required' handling for override completion (dotnet#62422)
  ...
@allisonchou allisonchou modified the milestones: Next, 17.4 P1 Jul 26, 2022
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.

5 participants