Skip to content

Commit 0d02f6b

Browse files
perf: use ValueListBuilder for PrivatePrintLeadingTrivia
1 parent 8a6fb62 commit 0d02f6b

File tree

3 files changed

+41
-31
lines changed

3 files changed

+41
-31
lines changed

Src/CSharpier.Core/CSharp/SyntaxPrinter/SyntaxNodePrinters/CompilationUnit.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,14 @@ public static Doc Print(CompilationUnitSyntax node, PrintingContext context)
2929
&& previousList.Contents[^2] is HardLine
3030
)
3131
{
32-
while (list.Contents[0] is HardLine { SkipBreakIfFirstInGroup: true })
32+
for (
33+
var i = 0;
34+
i < list.Contents.Count
35+
&& list.Contents[i] is HardLine { SkipBreakIfFirstInGroup: true };
36+
i++
37+
)
3338
{
34-
list.Contents.RemoveAt(0);
39+
docs[i] = Doc.Null;
3540
}
3641

3742
docs.Add(finalTrivia);

Src/CSharpier.Core/CSharp/SyntaxPrinter/Token.cs

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ private static Doc PrivatePrintLeadingTrivia(
237237
return Doc.Null;
238238
}
239239

240-
var docs = new List<Doc>();
240+
var docs = new ValueListBuilder<Doc>([null, null, null, null, null, null, null, null]);
241241

242242
// we don't print any new lines until we run into a comment or directive
243243
// the PrintExtraNewLines method takes care of printing the initial new lines for a given node
@@ -250,28 +250,28 @@ private static Doc PrivatePrintLeadingTrivia(
250250

251251
if (printNewLines && kind == SyntaxKind.EndOfLineTrivia)
252252
{
253-
if (docs.Count > 0 && docs[^1] == Doc.HardLineSkipBreakIfFirstInGroup)
253+
if (docs.Length > 0 && docs[^1] == Doc.HardLineSkipBreakIfFirstInGroup)
254254
{
255255
printNewLines = false;
256256
}
257257

258258
if (
259259
!(
260-
docs.Count > 1
260+
docs.Length > 1
261261
&& docs[^1] == Doc.HardLineSkipBreakIfFirstInGroup
262262
&& docs[^2] is LeadingComment { Type: CommentType.SingleLine }
263263
)
264264
)
265265
{
266-
docs.Add(Doc.HardLineSkipBreakIfFirstInGroup);
266+
docs.Append(Doc.HardLineSkipBreakIfFirstInGroup);
267267
}
268268
}
269269
if (kind is not (SyntaxKind.EndOfLineTrivia or SyntaxKind.WhitespaceTrivia))
270270
{
271271
printNewLines = true;
272272
}
273273

274-
void AddLeadingComment(CommentType commentType)
274+
void AddLeadingComment(CommentType commentType, ref ValueListBuilder<Doc> docs)
275275
{
276276
var comment = trivia.ToFullString().TrimEnd('\n', '\r');
277277
if (
@@ -283,43 +283,43 @@ void AddLeadingComment(CommentType commentType)
283283
comment = leadingTrivia[x - 1] + comment;
284284
}
285285

286-
docs.Add(Doc.LeadingComment(comment, commentType));
286+
docs.Append(Doc.LeadingComment(comment, commentType));
287287
}
288288

289289
if (IsSingleLineComment(kind))
290290
{
291-
AddLeadingComment(CommentType.SingleLine);
292-
docs.Add(
291+
AddLeadingComment(CommentType.SingleLine, ref docs);
292+
docs.Append(
293293
kind == SyntaxKind.SingleLineDocumentationCommentTrivia
294294
? Doc.HardLineSkipBreakIfFirstInGroup
295295
: Doc.Null
296296
);
297297
}
298298
else if (IsMultiLineComment(kind))
299299
{
300-
AddLeadingComment(CommentType.MultiLine);
300+
AddLeadingComment(CommentType.MultiLine, ref docs);
301301
}
302302
else if (kind == SyntaxKind.DisabledTextTrivia)
303303
{
304-
docs.Add(Doc.Trim, trivia.ToString());
304+
docs.Append(Doc.Trim, trivia.ToString());
305305
}
306306
else if (IsRegion(kind))
307307
{
308308
var triviaText = trivia.ToString();
309-
docs.Add(Doc.HardLineIfNoPreviousLine);
310-
docs.Add(Doc.Trim);
311-
docs.Add(
309+
docs.Append(Doc.HardLineIfNoPreviousLine);
310+
docs.Append(Doc.Trim);
311+
docs.Append(
312312
kind == SyntaxKind.RegionDirectiveTrivia
313313
? Doc.BeginRegion(triviaText)
314314
: Doc.EndRegion(triviaText)
315315
);
316-
docs.Add(Doc.HardLine);
316+
docs.Append(Doc.HardLine);
317317
}
318318
else if (trivia.IsDirective)
319319
{
320320
var triviaText = trivia.ToString();
321321

322-
docs.Add(
322+
docs.Append(
323323
// adding two of these to ensure we get a new line when a directive follows a trailing comment
324324
Doc.HardLineIfNoPreviousLineSkipBreakIfFirstInGroup,
325325
Doc.HardLineIfNoPreviousLineSkipBreakIfFirstInGroup,
@@ -337,16 +337,16 @@ void AddLeadingComment(CommentType commentType)
337337
)
338338
{
339339
x++;
340-
docs.Add(Doc.HardLineSkipBreakIfFirstInGroup);
340+
docs.Append(Doc.HardLineSkipBreakIfFirstInGroup);
341341
}
342342
printNewLines = false;
343343
}
344344
}
345345
}
346346

347-
while (skipLastHardline && docs.Count != 0 && docs.Last() is HardLine or NullDoc)
347+
while (skipLastHardline && docs.Length != 0 && docs[^1] is HardLine or NullDoc)
348348
{
349-
docs.RemoveAt(docs.Count - 1);
349+
docs.Pop();
350350
}
351351

352352
if (context.State.NextTriviaNeedsLine)
@@ -362,7 +362,7 @@ void AddLeadingComment(CommentType commentType)
362362
}
363363
else
364364
{
365-
var index = docs.Count - 1;
365+
var index = docs.Length - 1;
366366
while (
367367
index >= 0
368368
&& (docs[index] is HardLine or LeadingComment || docs[index] == Doc.Null)
@@ -373,7 +373,7 @@ void AddLeadingComment(CommentType commentType)
373373
// this handles an edge case where we get here but already added the line
374374
// it relates to the fact that single line comments include new line directives
375375
if (
376-
index + 2 >= docs.Count
376+
index + 2 >= docs.Length
377377
|| !(docs[index + 1] is HardLine && docs[index + 2] is HardLine)
378378
)
379379
{
@@ -383,7 +383,7 @@ void AddLeadingComment(CommentType commentType)
383383
context.State.NextTriviaNeedsLine = false;
384384
}
385385

386-
return docs.Count > 0 ? Doc.Concat(docs) : Doc.Null;
386+
return Doc.Concat(ref docs);
387387
}
388388

389389
private static bool IsSingleLineComment(SyntaxKind kind) =>

Src/CSharpier.Core/Utilities/ValueListBuilder.cs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,18 +87,16 @@ private void AppendMultiChar(scoped ReadOnlySpan<T> source)
8787
this.pos += source.Length;
8888
}
8989

90-
public void Insert(int index, scoped ReadOnlySpan<T> source)
90+
public void Insert(int index, T item)
9191
{
92-
Debug.Assert(index == 0, "Implementation currently only supports index == 0");
93-
94-
if ((uint)(this.pos + source.Length) > (uint)this.span.Length)
92+
if ((uint)(this.pos + 1) > (uint)this.span.Length)
9593
{
96-
this.Grow(source.Length);
94+
this.Grow(1);
9795
}
9896

99-
this.span[..this.pos].CopyTo(this.span[source.Length..]);
100-
source.CopyTo(this.span);
101-
this.pos += source.Length;
97+
span.Slice(index, this.pos - index).CopyTo(this.span.Slice(index + 1));
98+
this.span[index] = item;
99+
this.pos += 1;
102100
}
103101

104102
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -139,6 +137,13 @@ private void AddWithResize(T item)
139137
this.pos = pos + 1;
140138
}
141139

140+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
141+
public T Pop()
142+
{
143+
this.pos--;
144+
return this.span[this.pos];
145+
}
146+
142147
public readonly ReadOnlySpan<T> AsSpan()
143148
{
144149
return this.span[..this.pos];

0 commit comments

Comments
 (0)