Consider batching calls to GC.AddMemoryPressure
Maintainers usually reply within 1 day
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 35/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Stale
- Tech stack
- csharp
- Domain
- performance
Research direction
Start by locating the existing calls to GC.AddMemoryPressure and GC.RemoveMemoryPressure and the benchmark described in the issue. Compare batched 64 KB threshold behavior across the reported .NET versions, and consider the work done when the benchmark results show reduced collection overhead without incorrect memory-pressure accounting.
Written by the indexing model from the issue text.
Description
Describe the enhancement requested
In an internal project where I'm looking at the overhead of translating JSON responses into Arrow, I'm seeing the following performance characteristics:
.NET 4.7.2
| Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated |
|---|---|---|---|---|---|---|---|
| SystemTextJson | 663.9 us | 3.32 us | 3.10 us | 58.5938 | 19.5313 | - | 366.89 KB |
| Arrow | 666.3 us | 5.77 us | 5.11 us | 7756.8359 | 965.8203 | 117.1875 | 97.06 KB |
.NET 8.0
| Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated |
|---|---|---|---|---|---|---|---|
| SystemTextJson | 285.6 us | 1.00 us | 0.94 us | 23.4375 | 11.7188 | - | 363.92 KB |
| Arrow | 334.2 us | 6.46 us | 6.34 us | 199.7070 | 199.7070 | 199.7070 | 52.17 KB |
.NET 10.0
| Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated |
|---|---|---|---|---|---|---|---|
| SystemTextJson | 267.2 us | 1.42 us | 1.26 us | 23.4375 | 14.1602 | - | 362.37 KB |
| Arrow | 331.9 us | 6.23 us | 5.83 us | 198.7305 | 198.7305 | 198.7305 | 48.44 KB |
When I effectively remove the calls to GC.AddMemoryPressure and GC.RemoveMemoryPressure but make no other changes, I instead get the following:
.NET 4.7.2
| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
|---|---|---|---|---|---|---|
| SystemTextJson | 661.6 us | 3.45 us | 3.23 us | 58.5938 | 19.5313 | 366.91 KB |
| Arrow | 453.6 us | 8.35 us | 7.81 us | 7.8125 | 3.9063 | 53.68 KB |
.NET 8.0
| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
|---|---|---|---|---|---|---|
| SystemTextJson | 288.0 us | 2.57 us | 2.41 us | 23.4375 | 11.7188 | 363.92 KB |
| Arrow | 277.9 us | 4.47 us | 3.73 us | 2.9297 | 2.4414 | 52.11 KB |
.NET 10.0
| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
|---|---|---|---|---|---|---|
| SystemTextJson | 270.4 us | 1.77 us | 1.66 us | 23.4375 | 14.1602 | 362.37 KB |
| Arrow | 274.6 us | 3.46 us | 3.24 us | 2.9297 | 2.4414 | 48.3 KB |
The amount allocated by the "SystemTextJson" test is a reasonable proxy for the amount of native memory allocated by the "Arrow" test. Especially under .NET 4.7.2, it appears that these calls are triggering frequent garbage collection which (at least in a microbenchmark) are having a large effect on performance.
One way to deal with this is to effectively batch the calls. For instance, we might consider rounding up to 64 KB and only adding or removing memory pressure when we go past that threshold. For instance, the first allocation of 128 bytes would add 64 KB, then subsequent allocations of 128 bytes, 4096 bytes, 8192 bytes and 32768 bytes would only increment an internal counter. At that point, an allocation of 40000 bytes would push us past the next 64 KB boundary and trigger another GC.AddMemoryPressure for another 64 KB.
It's possible, of course, that the benchmark is pathological due to an overall heap size which is quite small at that point and that in a "real" application we would not see this kind of noise. I'll try to figure out a way to measure that.
- Dominant language
- C#
- Stars
- 41
- Forks
- 31
- Avg merge
- 20h 56m
- Merged PRs (30d)
- 14
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from apache/arrow-dotnet
-
Difficulty 1/5 1-3 hours Newbie friendliness 88/100
apache/arrow-dotnet#410 · 4 comments ·
Maintainers usually reply within 1 day
-
ArrowArrayConcatenator: null arrays are refused, and dictionary arrays lose their dictionaryPossibly taken @CurtHagenlocher claimed this 10 days ago. Open
Difficulty 4/5 3-5 days Newbie friendliness 68/100
apache/arrow-dotnet#446 ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 38/100
apache/arrow-dotnet#409 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
apache/arrow-dotnet#397 · 2 comments ·
Maintainers usually reply within 1 day
-
Difficulty 3/5 1-2 days Newbie friendliness 55/100
apache/arrow-dotnet#378 ·
Maintainers usually reply within 1 day
All issues in apache/arrow-dotnet
Similar issues
-
Python: Bug: split_plaintext_paragraph / split_markdown_paragraph can return a chunk larger than max_tokensPossibly taken @xThreeh claimed this today. Openpython triage
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
microsoft/semantic-kernel#14566 ·
Maintainers usually reply within 4 days
-
triage
Difficulty 1/5 Under an hour Newbie friendliness 82/100
rjmurillo/moq.analyzers#1384 ·
-
Variables passed to Compensated are not set on the routing slipMay be free again A pull request for this issue was closed without being merged. Open
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
MassTransit/MassTransit#6249 ·
-
security
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Sendspin/sendspin-dotnet#339 ·
Maintainers usually reply within 1 day
-
Difficulty 1/5 Under an hour Newbie friendliness 88/100
owasp-dep-scan/dosai#79 ·
Maintainers usually reply within 1 day