Skip to content

Commit 893942c

Browse files
authored
Slight allocation reduction in CommandLineParser.FlattenArgs (#79139)
* Slight allocation reduction in CommandLineParser.FlattenArgs This code previously created an ArrayBuilder over the rawArguments given and did some funky manipulations in support of response file handling. This PR removes that extra ArrayBuilder and it's associated allocations (these lists end up being large enough to exceed the pooling threshold). I think the new code is also a bit easier to understand, particularly in the non-response file section of the code. (No copying into a list, reversing that list, walking it backwards, walking another list backwards, copying into an unused section of the first list, making that section used again, etc) This only reduces allocations by ~5 MB when opening the roslyn sln, but it also seems simpler and easier to understand.
1 parent 05fc006 commit 893942c

File tree

1 file changed

+12
-22
lines changed

1 file changed

+12
-22
lines changed

src/Compilers/Core/Portable/CommandLine/CommandLineParser.cs

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -509,22 +509,22 @@ internal void FlattenArgs(
509509
bool sourceFileSeen = false;
510510
bool optionsEnded = false;
511511

512-
var args = ArrayBuilder<string>.GetInstance();
513-
args.AddRange(rawArguments);
514-
args.ReverseContents();
515-
var argsIndex = args.Count - 1;
516-
while (argsIndex >= 0)
512+
foreach (string arg in rawArguments)
513+
{
514+
processArg(arg);
515+
}
516+
517+
void processArg(string arg)
517518
{
518519
// EDMAURER trim off whitespace. Otherwise behavioral differences arise
519520
// when the strings which represent args are constructed by cmd or users.
520521
// cmd won't produce args with whitespace at the end.
521-
string arg = args[argsIndex].TrimEnd();
522-
argsIndex--;
522+
arg = arg.TrimEnd();
523523

524524
if (parsingScriptArgs)
525525
{
526526
scriptArgsOpt!.Add(arg);
527-
continue;
527+
return;
528528
}
529529

530530
if (scriptArgsOpt != null)
@@ -541,15 +541,15 @@ internal void FlattenArgs(
541541
// csi/vbi: at most one script can be specified on command line, anything else is a script arg:
542542
parsingScriptArgs = true;
543543
scriptArgsOpt.Add(arg);
544-
continue;
544+
return;
545545
}
546546

547547
if (!optionsEnded && arg == "--")
548548
{
549549
// csi/vbi: no argument past "--" should be treated as an option/response file
550550
optionsEnded = true;
551551
processedArgs.Add(arg);
552-
continue;
552+
return;
553553
}
554554
}
555555

@@ -586,7 +586,6 @@ internal void FlattenArgs(
586586
sourceFileSeen |= optionsEnded || !IsOption(arg);
587587
}
588588
}
589-
args.Free();
590589

591590
void parseResponseFile(string fullPath)
592591
{
@@ -653,21 +652,12 @@ void parseResponseFile(string fullPath)
653652
return;
654653
}
655654

656-
for (var i = splitList.Count - 1; i >= 0; i--)
655+
foreach (var newArg in splitList)
657656
{
658-
var newArg = splitList[i];
659657
// Ignores /noconfig option specified in a response file
660658
if (!string.Equals(newArg, "/noconfig", StringComparison.OrdinalIgnoreCase) && !string.Equals(newArg, "-noconfig", StringComparison.OrdinalIgnoreCase))
661659
{
662-
argsIndex++;
663-
if (argsIndex < args.Count)
664-
{
665-
args[argsIndex] = newArg;
666-
}
667-
else
668-
{
669-
args.Add(newArg);
670-
}
660+
processArg(newArg);
671661
}
672662
else
673663
{

0 commit comments

Comments
 (0)