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
Tagging subscribers to this area: @eiriktsarpalis
See info in area-owners.md if you want to be subscribed.
@lindexi is this just a general observation, or is this causing performance impact in your own application?
@danmosemsft this is just a general observation.
@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.
Apologies - I mixed this up with the other perf issue you opened (for registry). I have not evaluated this one.
@lindexi would you like to send a PR?
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:
https://github.com/dotnet/runtime/blob/f4d39134b8daefb5ab0db6750a203f980eecb4f0/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessManager.Win32.cs#L346
and similarly for Linux: https://github.com/dotnet/runtime/blob/6072e4d3a7a2a1493f514cdf4be75a3d56580e84/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessManager.Linux.cs#L187
Most helpful comment
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:
https://github.com/dotnet/runtime/blob/f4d39134b8daefb5ab0db6750a203f980eecb4f0/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessManager.Win32.cs#L346
and similarly for Linux: https://github.com/dotnet/runtime/blob/6072e4d3a7a2a1493f514cdf4be75a3d56580e84/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessManager.Linux.cs#L187