-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Optimize allocations in TextReader.ReadToEnd utilized by SourceText.From #70017
Optimize allocations in TextReader.ReadToEnd utilized by SourceText.From #70017
Conversation
The profile I'm looking currently shows 9.4% of allocation in our codeanalysis process under SourceText.From. These allocations occur during the TextReader.ReadToEnd call. Fortunately, Roslyn is already passing in a TextReader that knows it's length, and thus we can optimize this path. In netfx, this should at least get rid of the extra sizing allocations done during TextReader.ReadToEnd as it appends to it's internal stringbuilder. So, this should see a reduction of about 20% of the allocations in this codepath. In netcore (which is the case for this profile), we do better as this essentially gets rid of all allocations except for the equivalent of the StringBuilder.ToString call. So, this should see a reduction of about 2/3 of the allocations of this codepath.
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.
Actually, the previous impl ended up calling LargeText.Decode
if the length was greater than LargeObjectHeapLimitInChars
. The new impl would allocate the string on LOH
Should we call SourceText.From(reader, length, encoding, checksumAlgorithm)
from CreateText?
public override string ReadToEnd() | ||
{ | ||
#if NETCOREAPP | ||
return string.Create(Length, this, static (chars, state) => state.Read(chars)); |
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.
snazzy.
That's a good observation. I thought I was being smart with the TextFactoryService change, but I didn't consider the LOH case. In reply to: 1633907243 |
…override that takes in the length as it prevents LOH allocations.
The profile I'm looking currently shows 9.4% of allocation in our codeanalysis process under SourceText.From. These allocations occur during the TextReader.ReadToEnd call. Fortunately, Roslyn is already passing in a TextReader that knows it's length, and thus we can optimize this path.
In netfx, this should at least get rid of the extra sizing allocations done during TextReader.ReadToEnd as it appends to it's internal stringbuilder. So, this should see a reduction of about 20% of the allocations in this codepath.
In netcore (which is the case for this profile), we do better as this essentially gets rid of all allocations except for the equivalent of the StringBuilder.ToString call. So, this should see a reduction of about 2/3 of the allocations of this codepath.