Skip to content

Compiler: Avoid allocating strings for various variable and parameter names during code generation#12103

Merged
DustinCampbell merged 10 commits intodotnet:mainfrom
DustinCampbell:writeable-values
Aug 20, 2025
Merged

Compiler: Avoid allocating strings for various variable and parameter names during code generation#12103
DustinCampbell merged 10 commits intodotnet:mainfrom
DustinCampbell:writeable-values

Conversation

@DustinCampbell
Copy link
Member

@DustinCampbell DustinCampbell commented Aug 13, 2025

This change is targeted primarily at ScopeStack and TypeInferenceMethodParameter. Each of these holds onto strings that are created for variable names written during code generation. These variable names all take the form of some well-formed prefix and a suffix generated from int values, i.e. "__seq0". We can avoid allocating these strings by providing lightweight abstractions to hold the bits that change (i.e. the suffix data) and write the data directly.


CI Build: https://dev.azure.com/dnceng/internal/_build/results?buildId=2771119&view=results
Test Insertion: https://dev.azure.com/devdiv/DevDiv/_git/VS/pullrequest/661321
Toolset Run: https://dev.azure.com/dnceng/internal/_build/results?buildId=2771120&view=results

@DustinCampbell DustinCampbell requested a review from a team as a code owner August 13, 2025 13:54
@DustinCampbell DustinCampbell requested a review from a team August 13, 2025 13:54
{
public static int CountDigits(this int number)
{
var value = number < 0 ? (uint)-(number + 1) + 1 : (uint)number;
Copy link
Member

Choose a reason for hiding this comment

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

Nit: I get what this is avoiding, but it took me a moment, and iirc you had to do something similar in a recent PR? Is there something we can extract?

Copy link
Member Author

@DustinCampbell DustinCampbell Aug 14, 2025

Choose a reason for hiding this comment

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

I did have to do something similar in #12101, is that what you were thinking of? It's not really shareable though.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, that's what I was thinking of. If I hadn't glanced through that PR, I probably would have struggled more with what this is doing. Could we leave a comment about using uint to avoid overflow on minval?

Copy link
Contributor

Choose a reason for hiding this comment

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

Could you be less smart and just cast to a long? Ie, something like:

var value = number < 0 ? -(long)number : number;

Copy link
Contributor

Choose a reason for hiding this comment

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

Just out of curiosity, was using a long less desirable?

@DustinCampbell DustinCampbell changed the base branch from dev/dustinca/write-integers-allocation-free to main August 18, 2025 15:28
`IWriteableValue` is an abstraction for values that can be written to a `CodeWriter`.
This is a straightforward extension method in int that will count the number of digits in the int.
Introduce `BuilderName` to avoid allocating a new string for every "builder" variable in scope stack.
These ensure that the compiler doesn't allocate new strings for the rendermode and formname variable names in each scope.
- Remove #nullable disable
- Mark as sealed
- Store current entry in field and defer creating stack
- Add Scope ref struct to auto-close scopes.
- Avoid boxing `CSharpCodeWritingScope` to `IDisposable`
Avoid allocating extra strings for generic type parameters and arguments.
Add debugger display for BuilderVariableName, RenderModeVariableName, FormNameVariableName, SeqName, ParameterName, and TypeInferenceArgName.
@DustinCampbell DustinCampbell merged commit e8cac27 into dotnet:main Aug 20, 2025
11 checks passed
@DustinCampbell DustinCampbell deleted the writeable-values branch August 20, 2025 00:02
@dotnet-policy-service dotnet-policy-service bot added this to the Next milestone Aug 20, 2025
@RikkiGibson RikkiGibson modified the milestones: Next, 18.0 P1 Aug 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants