-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Reduce memory allocations for Process.GetProcessesByName #41137
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
Closed
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Can Linq's
Where
andToArray
be used here or would this allocate more?Uh oh!
There was an error while loading. Please reload this page.
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.
Do you mean anything like this (and then Where(...) in another file)? That was my initial idea but then I realized that it allocates more and affects the paths when we don't filter anything.
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 mean something like this:
So if a filter is given, this saves the allocation for
Process[] processes = new Process[processInfos.Length];
.Note: I changed the argument from
Predicate
toFun<,>
.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, I will aply the note and see if other guys will approve too.
I was confused by the following line from the ticket and just did the same for some reason:
runtime/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessManager.Win32.cs
Line 360 in f4d3913
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.
It would be useful to benchmark both time and total allocations for baseline and different variants of the fix.
Linq maybe saves some allocations, but it comes with other overheads and much larger static footprint so it is not a clear winner. We tend to avoid Linq in the runtime libraries implementation.
Uh oh!
There was an error while loading. Please reload this page.
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 am more worried about
ProcessManager.GetProcessInfos
above being so expensive (both in time and allocations) that the changes proposed here won't make any difference.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.
Maybe we can use this code
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 thinks it's better to go a step back and eleminate the allocations from
ProcessManager.GetProcessInfos
. There can be a internal version that doesn't need to return an array -- so the final array just have to be allocated before returning the results. All intermediate stepds shouldn't need arrays.I'll have to dig more into the code, to give a more concrete suggestion if you want.
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 thought about this option and found 2 ways that time:
Passing a filter through all the methods (but there are quite a few calls).
I didn't think a lot about this option because I thought it would complicate/litter the code without enough reason.
IEnumerable (or kind of that) as a return type for all non-public methods in the chain.
This one is better imo. But the thing is that
ProcessInfo[] ProcessManager.GetProcessInfos(string machineName)
is public and even the nextProcessInfo[] NtProcessManager.GetProcessInfos(string machineName, bool isRemoteMachine)
is public too.Unfortunately, that is not true.
Feel free to find a better way. If you find one, I can change this PR or let you create a new one.
My plan is still to measure performance of 3 approaches discussed above.
Interesting idea but not sure if it could help. As a result we need an array of Processes, not ProcessInfos. So the actual issue is that we don't know the right length in advance. The only way to get this value is to interate one more time.
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.
We could use the same approach as File/Directory enumeration API does with
public ref partial struct FileSystemEntry
.