Skip to content
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

Can the GetProcessesByName method reduce the number of arrays and Process objects created? #40768

Closed
lindexi opened this issue Aug 13, 2020 · 9 comments
Labels
area-System.Diagnostics.Process backlog-cleanup-candidate An inactive issue that has been marked for automated closure. help wanted [up-for-grabs] Good issue for external contributors no-recent-activity tenet-performance Performance related issue

Comments

@lindexi
Copy link
Member

lindexi commented Aug 13, 2020

Description

As written in the code, GetProcessesByName first calls GetProcesses to obtain all processes of the machine, and then filters the process name

        public static Process[] GetProcessesByName(string? processName, string machineName)
        {
            if (processName == null)
            {
                processName = string.Empty;
            }

            Process[] procs = GetProcesses(machineName);
            var list = new List<Process>();

            for (int i = 0; i < procs.Length; i++)
            {
                if (string.Equals(processName, procs[i].ProcessName, StringComparison.OrdinalIgnoreCase))
                {
                    list.Add(procs[i]);
                }
                else
                {
                    procs[i].Dispose();
                }
            }

            return list.ToArray();
        }

But in fact, we can filter the process name in GetProcesses in advance.

        public static Process[] GetProcesses(string machineName)
        {
            bool isRemoteMachine = ProcessManager.IsRemoteMachine(machineName);
            ProcessInfo[] processInfos = ProcessManager.GetProcessInfos(machineName);
            Process[] processes = new Process[processInfos.Length];
            for (int i = 0; i < processInfos.Length; i++)
            {
                ProcessInfo processInfo = processInfos[i];
                processes[i] = new Process(machineName, isRemoteMachine, processInfo.ProcessId, processInfo);
            }
            return processes;
        }

If we do this, we can reduce the allocation length of the Process array and create some Process objects in the GetProcesses method

@lindexi lindexi added the tenet-performance Performance related issue label Aug 13, 2020
@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added area-System.Diagnostics.Process untriaged New issue has not been triaged by the area owner labels Aug 13, 2020
@ghost
Copy link

ghost commented Aug 13, 2020

Tagging subscribers to this area: @eiriktsarpalis
See info in area-owners.md if you want to be subscribed.

@danmoseley
Copy link
Member

@lindexi is this just a general observation, or is this causing performance impact in your own application?

@lindexi
Copy link
Member Author

lindexi commented Aug 14, 2020

@danmosemsft this is just a general observation.

@danmoseley
Copy link
Member

@lindexi thanks, but unless something is self-evidently inefficient, we would need perf numbers to motivate increasing the complexity in this way. I will close this: feel free to reopen if you have such numbers. We recommend use of Benchmark.NET. I do agree with @jkotas that I do not think you will see a benefit.

@danmoseley
Copy link
Member

Apologies - I mixed this up with the other perf issue you opened (for registry). I have not evaluated this one.

@adamsitnik adamsitnik added this to the Future milestone Aug 14, 2020
@adamsitnik adamsitnik added help wanted [up-for-grabs] Good issue for external contributors and removed untriaged New issue has not been triaged by the area owner labels Aug 14, 2020
@adamsitnik
Copy link
Member

@lindexi would you like to send a PR?

@felipepessoto
Copy link
Contributor

If we want to reduce memory allocation, we may want to filter the process name all the way through the NtProcessInfoHelper.GetProcessInfos, for Windows, where we have SYSTEM_PROCESS_INFORMATION.ImageName:

private static unsafe ProcessInfo[] GetProcessInfos(ReadOnlySpan<byte> data, Predicate<int>? processIdFilter)

and similarly for Linux:

internal static IEnumerable<int> EnumerateProcessIds()

Copy link
Contributor

Due to lack of recent activity, this issue has been marked as a candidate for backlog cleanup. It will be closed if no further activity occurs within 14 more days. Any new comment (by anyone, not necessarily the author) will undo this process.

This process is part of our issue cleanup automation.

@dotnet-policy-service dotnet-policy-service bot added backlog-cleanup-candidate An inactive issue that has been marked for automated closure. no-recent-activity labels Feb 14, 2025
Copy link
Contributor

This issue will now be closed since it had been marked no-recent-activity but received no further activity in the past 14 days. It is still possible to reopen or comment on the issue, but please note that the issue will be locked if it remains inactive for another 30 days.

@dotnet-policy-service dotnet-policy-service bot removed this from the Future milestone Mar 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-System.Diagnostics.Process backlog-cleanup-candidate An inactive issue that has been marked for automated closure. help wanted [up-for-grabs] Good issue for external contributors no-recent-activity tenet-performance Performance related issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants