Skip to content

Commit 516ad84

Browse files
authored
Reduce allocations during SourceGeneration (#78403)
SourceGenerator.DoGenerate was previously writing the text into a StringBuilder, wrapping that in a TextReader, and creating a SourceText from that. Creation of that source text would end up allocating in SourceText.From (likely from calling ReadToEnd in the give text reader) Instead, we can use a copy of the (unused) StringBuilderText and just use that as the source text.
1 parent fdbbf6b commit 516ad84

File tree

1 file changed

+14
-32
lines changed

1 file changed

+14
-32
lines changed

src/Tools/Source/CompilerGeneratorTools/Source/CSharpSyntaxGenerator/SourceGenerator.cs

Lines changed: 14 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ void addResult(Action<TextWriter> writeFunction, string hintName)
123123
}
124124

125125
// And create a SourceText from the StringBuilder, once again avoiding allocating a single massive string
126-
var sourceText = SourceText.From(new StringBuilderReader(stringBuilder), stringBuilder.Length, encoding: Encoding.UTF8);
126+
var sourceText = new StringBuilderText(stringBuilder, encoding: Encoding.UTF8);
127127
context.AddSource(hintName, sourceText);
128128
}
129129
}
@@ -168,44 +168,26 @@ public override int Read(char[] buffer, int index, int count)
168168
}
169169
}
170170

171-
private sealed class StringBuilderReader : TextReader
171+
private sealed class StringBuilderText : SourceText
172172
{
173-
private readonly StringBuilder _stringBuilder;
174-
private int _position;
173+
private readonly StringBuilder _builder;
174+
private readonly Encoding? _encoding;
175175

176-
public StringBuilderReader(StringBuilder stringBuilder)
176+
public StringBuilderText(StringBuilder builder, Encoding? encoding)
177177
{
178-
_stringBuilder = stringBuilder;
179-
_position = 0;
178+
_builder = builder;
179+
_encoding = encoding;
180180
}
181181

182-
public override int Peek()
183-
{
184-
if (_position == _stringBuilder.Length)
185-
{
186-
return -1;
187-
}
182+
public override Encoding? Encoding => _encoding;
183+
public override int Length => _builder.Length;
184+
public override char this[int position] => _builder[position];
188185

189-
return _stringBuilder[_position];
190-
}
186+
public override string ToString(TextSpan span)
187+
=> _builder.ToString(span.Start, span.Length);
191188

192-
public override int Read()
193-
{
194-
if (_position == _stringBuilder.Length)
195-
{
196-
return -1;
197-
}
198-
199-
return _stringBuilder[_position++];
200-
}
201-
202-
public override int Read(char[] buffer, int index, int count)
203-
{
204-
var charsToCopy = Math.Min(count, _stringBuilder.Length - _position);
205-
_stringBuilder.CopyTo(_position, buffer, index, charsToCopy);
206-
_position += charsToCopy;
207-
return charsToCopy;
208-
}
189+
public override void CopyTo(int sourceIndex, char[] destination, int destinationIndex, int count)
190+
=> _builder.CopyTo(sourceIndex, destination, destinationIndex, count);
209191
}
210192
}
211193
}

0 commit comments

Comments
 (0)