-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Improve the performance of Environment.WorkingSet in Windows #26522
Conversation
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.
Please don't do this. If Environment.WorkingSet is performing poorly, let's fix Environment.WorkingSet, not duplicate its functionality in a private manner.
src/System.Private.CoreLib/src/System/Diagnostics/Eventing/RuntimeEventSourceHelper.Windows.cs
Outdated
Show resolved
Hide resolved
src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetProcessMemoryInfo.cs
Outdated
Show resolved
Hide resolved
…timeEventSourceHelper
src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetProcessMemoryInfo.cs
Outdated
Show resolved
Hide resolved
src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetProcessMemoryInfo.cs
Outdated
Show resolved
Hide resolved
src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetProcessMemoryInfo.cs
Outdated
Show resolved
Hide resolved
src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetProcessMemoryInfo.cs
Outdated
Show resolved
Hide resolved
src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetProcessMemoryInfo.cs
Outdated
Show resolved
Hide resolved
src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems
Show resolved
Hide resolved
src/System.Private.CoreLib/src/System/Diagnostics/Eventing/RuntimeEventSource.cs
Outdated
Show resolved
Hide resolved
src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetProcessMemoryInfo.cs
Outdated
Show resolved
Hide resolved
get | ||
{ | ||
Type? processType = Type.GetType("System.Diagnostics.Process, System.Diagnostics.Process, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", throwOnError: false); | ||
if (processType?.GetMethod("GetCurrentProcess")?.Invoke(null, BindingFlags.DoNotWrapExceptions, null, null, null) is IDisposable currentProcess) |
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 we need to fix the perf of this one too? How much more expensive is this compared to Windows? Does the cost of this show up in the profiles when you turn on performance counters that call this again and again?
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.
Ideally, yes. But my benchmarks using BenchmarkDotNet suggested that Linux is at a better state than Windows (>10x) so for now I'm fixing Windows first.
Linux:
| Method | N | Mean | Error | StdDev | Rank |
|----------- |------ |---------:|---------:|---------:|-----:|
| workingset | 10000 | 143.4 us | 2.520 us | 2.801 us | 1 |
Windows (before the fix):
| Method | N | Mean | Error | StdDev | Rank |
|----------- |------ |---------:|----------:|----------:|-----:|
| workingset | 10000 | 1.620 ms | 0.0153 ms | 0.0127 ms | 1 |
In addition to this, the customer requesting this fix is Bing and they are running on Windows.
That being said, the Linux overhead is also huge compared to what we have on Windows after this fix so ideally we'd like to fix it on Linux too:
| Method | N | Mean | Error | StdDev | Median | Rank |
|----------- |------ |---------:|----------:|----------:|---------:|-----:|
| workingset | 10000 | 851.6 ns | 16.916 ns | 34.556 ns | 835.9 ns | 1 |
src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetProcessMemoryInfo.cs
Outdated
Show resolved
Hide resolved
In corefx we currently assert on UWP that |
Yes, the changed behavior is fine. |
…26522) * Use win32 api directly for workingset counter * Fix build warnings * Removing useless code * more cleanup * remove size annotation * remove useless comment * Move all the changes to Environment.WorkingSet and remove it from RuntimeEventSourceHelper * removing useless usings * Use kernel32.dll instead of psapi.dll * Code review feedback * Remove newline change * More code review nits
…#27212) * Use win32 api directly for workingset counter * Fix build warnings * Removing useless code * more cleanup * remove size annotation * remove useless comment * Move all the changes to Environment.WorkingSet and remove it from RuntimeEventSourceHelper * removing useless usings * Use kernel32.dll instead of psapi.dll * Code review feedback * Remove newline change * More code review nits
This improves the performance of Environment.WorkingSet by calling Win32 API
GetProcessMemoryInfo
directly to fetch the working set size instead of doing reflection overSystem.Diagnostics.Process
and calling get_workingSet64 which does a bunch of allocations and additional API calls.On Linux, there is no simple native API to call and we need to parse procfs. However, from the same benchmark, the Linux is much, much faster than Window when we call
Environment.WorkingSet
so I don't think we need to replace it on Linux. (From my bare bones benchmark, it was ~1000x faster on a same machine).This fixes #23736.