-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Slight allocation reduction in CommandLineParser.FlattenArgs #79139
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
Slight allocation reduction in CommandLineParser.FlattenArgs #79139
Conversation
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.
args.ReverseContents(); | ||
var argsIndex = args.Count - 1; | ||
while (argsIndex >= 0) | ||
var argsEnumerator = rawArguments.GetEnumerator(); |
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.
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.
Not needed with recursive simplificiation
while (argsEnumerator.MoveNext()) | ||
notProcessedSplitList.Add(argsEnumerator.Current); | ||
|
||
argsEnumerator = notProcessedSplitList.GetEnumerator(); |
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.
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.
Not needed with recursive simplificiation
// Ignores /noconfig option specified in a response file | ||
if (!string.Equals(newArg, "/noconfig", StringComparison.OrdinalIgnoreCase) && !string.Equals(newArg, "-noconfig", StringComparison.OrdinalIgnoreCase)) | ||
if (string.Equals(newArg, "/noconfig", StringComparison.OrdinalIgnoreCase) || string.Equals(newArg, "-noconfig", StringComparison.OrdinalIgnoreCase)) |
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.
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.
done
var argsIndex = args.Count - 1; | ||
while (argsIndex >= 0) | ||
var argsEnumerator = rawArguments.GetEnumerator(); | ||
while (argsEnumerator.MoveNext()) |
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.
I would like to suggest an alternative approach.
- Extract the body of this loop into a local function, let's call it "void processArg(string arg)". It should start with trimming the
arg
, and do what the body of the loop does, assuming that acontinue
is replaced with areturn
. - Change this loop to plain
foreach
overrawArguments
, calling the new local function as the body. - Inside
parseResponseFile
, instead of doingnotProcessedSplitList.Add(newArg);
, callprocessArg(newArg)
. #Closed
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.
I like this idea, implemented in commit 2. Makes the code even easier to understand.
Done with review pass (commit 1) |
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.
LGTM (commit 2)
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.