Skip to content

Conversation

@ToddGrun
Copy link
Contributor

@ToddGrun ToddGrun commented Apr 22, 2025

Reduce allocations from executing NamespaceSymbol.GetExtensionContainers. This method accounts for 48% of allocations in our CodeAnalysis process during completion in our C# editing speedometer test. The changes in this PR reduce that to about 4.5%

The change here is to add an override of NamespaceSymbol.GetExtensionContainers to MergedNamespaceSymbol. Specifically, the base class implementation of GetExtensionContainers calls GetTypeMembersUnordered, which is inefficient when in a MergedNamespaceSymbol instance as it does a Linq OfType call and allocates an IA from that. Instead, the new override can just enumerate over the result of GetMembersUnordered directly, and do the check before calling into shared code with the base implementation.

*** Previous allocations during completion section of C# editing speedometer test ***
image

*** New allocations in NamespaceSymbol.GetTypeMembersUnordered ***
image

*** New allocations in MergedNamespaceSymbol.GetTypeMembersUnordered ***
image

…ordered

Going to create a test insertion to get numbers before moving out of draft mode.

Will add performance justification of the change at that point.
@ghost ghost added Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead labels Apr 22, 2025
…ontainers virtual and having MergedNamespaceSymbol implement it directly.
@ToddGrun ToddGrun changed the title *** WIP: Reduce allocations in MergedNamespaceSymbol.GetTypeMembersUnordered Reduce allocations in MergedNamespaceSymbol.GetExtensionContainers Apr 23, 2025
@ToddGrun ToddGrun marked this pull request as ready for review April 23, 2025 14:01
@ToddGrun ToddGrun requested a review from a team as a code owner April 23, 2025 14:01
@ToddGrun
Copy link
Contributor Author

@dotnet/roslyn-compiler -- This is ready for review

@ToddGrun ToddGrun changed the title Reduce allocations in MergedNamespaceSymbol.GetExtensionContainers Reduce allocations in NamespaceSymbol.GetExtensionContainers Apr 23, 2025

protected void AddExtensionContainersForType(NamedTypeSymbol type, ArrayBuilder<NamedTypeSymbol> extensions)
{
if (!type.IsReferenceType || !type.IsStatic || type.IsGenericType || !type.MightContainExtensionMethods) return;
Copy link
Contributor

Choose a reason for hiding this comment

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

IsReferenceType

I think we can replace this with IsClassType to optimize this code even 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.

That's not an obvious equivalence (for me, at least). I'd prefer not to make that change, but will if you would like me to.

Copy link
Contributor

@AlekseyTs AlekseyTs Apr 23, 2025

Choose a reason for hiding this comment

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

Consider at least adding a comment capturing the suggestion and starting with // Tracked by https://github.com/dotnet/roslyn/issues/76130 :

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in commit 5

}
}

protected void AddExtensionContainersForType(NamedTypeSymbol type, ArrayBuilder<NamedTypeSymbol> extensions)
Copy link
Contributor

@AlekseyTs AlekseyTs Apr 23, 2025

Choose a reason for hiding this comment

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

"AddExtensionContainersFromType" or "AddExtensionContainersInType"? #Closed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in commit 4

Copy link
Contributor

@AlekseyTs AlekseyTs left a comment

Choose a reason for hiding this comment

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

LGTM (commit 3)

@AlekseyTs AlekseyTs requested review from a team, jcouv and jjonescz April 23, 2025 15:17
Copy link
Contributor

@AlekseyTs AlekseyTs left a comment

Choose a reason for hiding this comment

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

LGTM (commit 4)

@ToddGrun ToddGrun merged commit 013c870 into dotnet:main Apr 23, 2025
24 checks passed
@dotnet-policy-service dotnet-policy-service bot added this to the Next milestone Apr 23, 2025
@RikkiGibson RikkiGibson modified the milestones: Next, 18.0 P1 Aug 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants