Skip to content

Conversation

@ToddGrun
Copy link
Contributor

@ToddGrun ToddGrun commented Sep 2, 2023

This method shows as 14.2% of allocations of the RoslynCodeAnalysisService process in a profile during a slow razor completion operation. Of that, 7.5% is attributable to ImmutableArray allocations. ToDisplayString previously would populate ArrayBuilder instances, allocate immutable arrays from them, iterate over the immutable arrays to generate a string, and then throw away the immutable arrays. Instead, we can just skip the ImmutableArrays completely and iterate over ArrayBuilders to generate the string.

image

Benchmarks code used to generate the following data is from the 2nd commit.

|              Method | OptimizeDisplayString |     Mean |    Error |   StdDev |   Gen0 | Allocated |
|-------------------- |---------------------- |---------:|---------:|---------:|-------:|----------:|
| CallToDisplayString |                 False | 843.0 ns | 16.89 ns | 45.08 ns | 0.0429 |     456 B |
| CallToDisplayString |                  True | 692.3 ns | 23.06 ns | 67.99 ns | 0.0248 |     264 B

This method shows as 5.9% of allocations in a profile during a slow completion operation. Of that, 3.1% is attributable to ImmutableArray allocations. ToDisplayString previously would populate ArrayBuilder instances, allocate immutable arrays from them, iterate over the immutable arrays to generate a string, and then throw away the immutable arrays. Instead, we can just skip the ImmutableArrays completely and iterate over ArrayBuilders to generate the string.
@ToddGrun ToddGrun requested review from a team as code owners September 2, 2023 00:24
@ghost ghost added Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead labels Sep 2, 2023
@ToddGrun ToddGrun requested a review from a team as a code owner September 2, 2023 00:25
{
if (parts is null)
{
throw new ArgumentException("parts");
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
throw new ArgumentException("parts");
throw new ArgumentNullException(nameof(parts));

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch, changed here and the code it was copied from

Comment on lines 75 to 78
if (parts.Count == 1)
{
return parts[0].ToString();
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if (parts.Count == 1)
{
return parts[0].ToString();
}
if (parts is [var singlePart])
{
return singlePart.ToString();
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm a bit hesitant to make this change. I'm not of the opinion that it improves readability in this case, and I think it might add a null check in the code.

@DoctorKrolic
Copy link
Contributor

Also does this fix #67067?

@ToddGrun
Copy link
Contributor Author

ToddGrun commented Sep 5, 2023

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 4 pipeline(s).

@ToddGrun
Copy link
Contributor Author

ToddGrun commented Sep 5, 2023

Also does this fix #67067?

I didn't know that bug existed, but this should partially address that bug. Since I don't have a bug tracking this, I'll go ahead and resolve that bug once this PR is in, as I think further allocation optimizations in this method would be quite a bit more involved.

@ToddGrun
Copy link
Contributor Author

ToddGrun commented Sep 5, 2023

@AlekseyTs @333fred ptal

@ToddGrun ToddGrun requested a review from a team as a code owner September 6, 2023 15:27
@ToddGrun ToddGrun force-pushed the dev/toddgrun/OptimizeToDisplayString branch from 01c2b62 to 91b0e80 Compare September 6, 2023 18:17
Copy link
Member

@333fred 333fred left a comment

Choose a reason for hiding this comment

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

Generally LGTM, but it looks like there are a couple of comments to address before approving.

@ToddGrun
Copy link
Contributor Author

ToddGrun commented Sep 6, 2023

Generally LGTM, but it looks like there are a couple of comments to address before approving.

Incorporated the nameof suggestion. Passed on the pattern matching suggestion as I'm not (yet) of the opinion that it improves readability. If you feel otherwise, I'm glad to switch it over.

}
finally
{
pool.Free();
Copy link
Member

Choose a reason for hiding this comment

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

I thought there was a ToStringAndFree helper for this pattern.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, there is. Changed this one and the one I copied this from.

@ToddGrun ToddGrun requested a review from AlekseyTs September 7, 2023 17:02
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.

Changes under Compilers LGTM (commit 5)

@ToddGrun ToddGrun merged commit f371529 into dotnet:main Sep 7, 2023
@ghost ghost added this to the Next milestone Sep 7, 2023
@Cosifne Cosifne removed this from the Next milestone Sep 25, 2023
@Cosifne Cosifne added this to the 17.8 P3 milestone Sep 25, 2023
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.

6 participants