perf(profiling): reduce ProfilesDictionary arena footprint#2246
perf(profiling): reduce ProfilesDictionary arena footprint#2246taegyunkim wants to merge 1 commit into
Conversation
📚 Documentation Check Results📦
|
db3ba31 to
a7fd92d
Compare
🔒 Cargo Deny Results📦
|
a7fd92d to
2a80270
Compare
BenchmarksComparisonBenchmark execution time: 2026-07-16 21:22:14 Comparing candidate commit 6b4ba8c in PR branch Found 4 performance improvements and 4 performance regressions! Performance is the same for 5 metrics, 0 unstable metrics.
|
| cpu_model | git_commit_sha | git_commit_date | git_branch |
|---|---|---|---|
| Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz | 6b4ba8c | 1784236353 | taegyun/reduce-profile-string-shards |
| scenario | metric | min | mean ± sd | median ± mad | p75 | p95 | p99 | max | peak_to_median_ratio | skewness | kurtosis | cv | sem | runs | sample_size |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| profile_serialize_compressed_pprof_timestamped_x1000 | execution_time | 977.869µs | 981.691µs ± 2.655µs | 980.904µs ± 0.843µs | 982.320µs | 985.186µs | 990.494µs | 1004.529µs | 2.41% | 4.154 | 28.467 | 0.27% | 0.188µs | 1 | 200 |
| scenario | metric | 95% CI mean | Shapiro-Wilk pvalue | Ljung-Box pvalue (lag=1) | Dip test pvalue |
|---|---|---|---|---|---|
| profile_serialize_compressed_pprof_timestamped_x1000 | execution_time | [981.323µs; 982.059µs] or [-0.037%; +0.037%] | None | None | None |
Group 2
| cpu_model | git_commit_sha | git_commit_date | git_branch |
|---|---|---|---|
| Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz | 6b4ba8c | 1784236353 | taegyun/reduce-profile-string-shards |
| scenario | metric | min | mean ± sd | median ± mad | p75 | p95 | p99 | max | peak_to_median_ratio | skewness | kurtosis | cv | sem | runs | sample_size |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| benching string interning on wordpress profile | execution_time | 113.156µs | 114.024µs ± 0.413µs | 113.986µs ± 0.193µs | 114.197µs | 114.414µs | 115.173µs | 118.010µs | 3.53% | 4.774 | 43.149 | 0.36% | 0.029µs | 1 | 200 |
| scenario | metric | 95% CI mean | Shapiro-Wilk pvalue | Ljung-Box pvalue (lag=1) | Dip test pvalue |
|---|---|---|---|---|---|
| benching string interning on wordpress profile | execution_time | [113.967µs; 114.081µs] or [-0.050%; +0.050%] | None | None | None |
Group 3
| cpu_model | git_commit_sha | git_commit_date | git_branch |
|---|---|---|---|
| Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz | 6b4ba8c | 1784236353 | taegyun/reduce-profile-string-shards |
| scenario | metric | min | mean ± sd | median ± mad | p75 | p95 | p99 | max | peak_to_median_ratio | skewness | kurtosis | cv | sem | runs | sample_size |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| profile_add_sample2_frames_x1000 | execution_time | 721.862µs | 723.252µs ± 0.487µs | 723.252µs ± 0.280µs | 723.509µs | 724.139µs | 724.511µs | 725.309µs | 0.28% | 0.540 | 1.600 | 0.07% | 0.034µs | 1 | 200 |
| scenario | metric | 95% CI mean | Shapiro-Wilk pvalue | Ljung-Box pvalue (lag=1) | Dip test pvalue |
|---|---|---|---|---|---|
| profile_add_sample2_frames_x1000 | execution_time | [723.185µs; 723.320µs] or [-0.009%; +0.009%] | None | None | None |
Group 4
| cpu_model | git_commit_sha | git_commit_date | git_branch |
|---|---|---|---|
| Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz | 6b4ba8c | 1784236353 | taegyun/reduce-profile-string-shards |
| scenario | metric | min | mean ± sd | median ± mad | p75 | p95 | p99 | max | peak_to_median_ratio | skewness | kurtosis | cv | sem | runs | sample_size |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| profile_add_sample_frames_x1000 | execution_time | 4.138ms | 4.142ms ± 0.003ms | 4.142ms ± 0.001ms | 4.144ms | 4.146ms | 4.148ms | 4.169ms | 0.66% | 4.476 | 39.639 | 0.07% | 0.000ms | 1 | 200 |
| scenario | metric | 95% CI mean | Shapiro-Wilk pvalue | Ljung-Box pvalue (lag=1) | Dip test pvalue |
|---|---|---|---|---|---|
| profile_add_sample_frames_x1000 | execution_time | [4.142ms; 4.143ms] or [-0.009%; +0.009%] | None | None | None |
Group 5
| cpu_model | git_commit_sha | git_commit_date | git_branch |
|---|---|---|---|
| Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz | 6b4ba8c | 1784236353 | taegyun/reduce-profile-string-shards |
| scenario | metric | min | mean ± sd | median ± mad | p75 | p95 | p99 | max | peak_to_median_ratio | skewness | kurtosis | cv | sem | runs | sample_size |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| profile_add_sample_timestamped_x1000 | execution_time | 4.111ms | 4.118ms ± 0.008ms | 4.117ms ± 0.002ms | 4.118ms | 4.121ms | 4.124ms | 4.227ms | 2.69% | 11.942 | 155.972 | 0.20% | 0.001ms | 1 | 200 |
| scenario | metric | 95% CI mean | Shapiro-Wilk pvalue | Ljung-Box pvalue (lag=1) | Dip test pvalue |
|---|---|---|---|---|---|
| profile_add_sample_timestamped_x1000 | execution_time | [4.117ms; 4.119ms] or [-0.028%; +0.028%] | None | None | None |
Group 6
| cpu_model | git_commit_sha | git_commit_date | git_branch |
|---|---|---|---|
| Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz | 6b4ba8c | 1784236353 | taegyun/reduce-profile-string-shards |
| scenario | metric | min | mean ± sd | median ± mad | p75 | p95 | p99 | max | peak_to_median_ratio | skewness | kurtosis | cv | sem | runs | sample_size |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| profiles_dictionary/profile_string_inserts/threads/1 | execution_time | 189.453µs | 190.490µs ± 0.520µs | 190.549µs ± 0.301µs | 190.887µs | 191.047µs | 191.088µs | 191.098µs | 0.29% | -0.795 | -0.324 | 0.26% | 0.164µs | 1 | 10 |
| profiles_dictionary/profile_string_inserts/threads/1 | throughput | 5358504.654op/s | 5375646.012op/s ± 14705.737op/s | 5373957.989op/s ± 8480.436op/s | 5379438.951op/s | 5400197.271op/s | 5404070.225op/s | 5405038.464op/s | 0.58% | 0.804 | -0.312 | 0.26% | 4650.362op/s | 1 | 10 |
| profiles_dictionary/profile_string_inserts/threads/16 | execution_time | 4.782ms | 4.837ms ± 0.024ms | 4.836ms ± 0.008ms | 4.847ms | 4.866ms | 4.877ms | 4.880ms | 0.90% | -0.763 | 1.523 | 0.48% | 0.008ms | 1 | 10 |
| profiles_dictionary/profile_string_inserts/threads/16 | throughput | 3357631.877op/s | 3387086.951op/s ± 17122.665op/s | 3387949.540op/s ± 5687.335op/s | 3390953.378op/s | 3410885.009op/s | 3423368.884op/s | 3426489.852op/s | 1.14% | 0.805 | 1.560 | 0.48% | 5414.662op/s | 1 | 10 |
| profiles_dictionary/profile_string_inserts/threads/2 | execution_time | 523.707µs | 525.298µs ± 0.874µs | 525.478µs ± 0.431µs | 525.655µs | 526.428µs | 526.799µs | 526.891µs | 0.27% | -0.120 | -0.063 | 0.16% | 0.276µs | 1 | 10 |
| profiles_dictionary/profile_string_inserts/threads/2 | throughput | 3886949.995op/s | 3898746.325op/s ± 6489.527op/s | 3897406.069op/s ± 3200.403op/s | 3901316.471op/s | 3908495.470op/s | 3910164.953op/s | 3910582.324op/s | 0.34% | 0.129 | -0.065 | 0.16% | 2052.169op/s | 1 | 10 |
| profiles_dictionary/profile_string_inserts/threads/4 | execution_time | 960.622µs | 962.947µs ± 2.080µs | 962.445µs ± 0.637µs | 962.865µs | 966.633µs | 967.588µs | 967.827µs | 0.56% | 1.423 | 1.137 | 0.20% | 0.658µs | 1 | 10 |
| profiles_dictionary/profile_string_inserts/threads/4 | throughput | 4232162.152op/s | 4253627.465op/s ± 9161.366op/s | 4255828.831op/s ± 2817.970op/s | 4258853.132op/s | 4261834.992op/s | 4263488.977op/s | 4263902.473op/s | 0.19% | -1.416 | 1.121 | 0.20% | 2897.078op/s | 1 | 10 |
| scenario | metric | 95% CI mean | Shapiro-Wilk pvalue | Ljung-Box pvalue (lag=1) | Dip test pvalue |
|---|---|---|---|---|---|
| profiles_dictionary/profile_string_inserts/threads/1 | execution_time | [190.168µs; 190.812µs] or [-0.169%; +0.169%] | None | None | None |
| profiles_dictionary/profile_string_inserts/threads/1 | throughput | [5366531.470op/s; 5384760.555op/s] or [-0.170%; +0.170%] | None | None | None |
| profiles_dictionary/profile_string_inserts/threads/16 | execution_time | [4.822ms; 4.852ms] or [-0.312%; +0.312%] | None | None | None |
| profiles_dictionary/profile_string_inserts/threads/16 | throughput | [3376474.409op/s; 3397699.494op/s] or [-0.313%; +0.313%] | None | None | None |
| profiles_dictionary/profile_string_inserts/threads/2 | execution_time | [524.757µs; 525.840µs] or [-0.103%; +0.103%] | None | None | None |
| profiles_dictionary/profile_string_inserts/threads/2 | throughput | [3894724.148op/s; 3902768.502op/s] or [-0.103%; +0.103%] | None | None | None |
| profiles_dictionary/profile_string_inserts/threads/4 | execution_time | [961.658µs; 964.236µs] or [-0.134%; +0.134%] | None | None | None |
| profiles_dictionary/profile_string_inserts/threads/4 | throughput | [4247949.295op/s; 4259305.634op/s] or [-0.133%; +0.133%] | None | None | None |
Baseline
Baseline benchmark details
Group 1
| cpu_model | git_commit_sha | git_commit_date | git_branch |
|---|---|---|---|
| Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz | 0c6e2a5 | 1784223782 | main |
| scenario | metric | min | mean ± sd | median ± mad | p75 | p95 | p99 | max | peak_to_median_ratio | skewness | kurtosis | cv | sem | runs | sample_size |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| profile_serialize_compressed_pprof_timestamped_x1000 | execution_time | 939.829µs | 944.623µs ± 2.504µs | 943.878µs ± 0.845µs | 945.314µs | 949.130µs | 951.744µs | 961.520µs | 1.87% | 2.288 | 9.944 | 0.26% | 0.177µs | 1 | 200 |
| scenario | metric | 95% CI mean | Shapiro-Wilk pvalue | Ljung-Box pvalue (lag=1) | Dip test pvalue |
|---|---|---|---|---|---|
| profile_serialize_compressed_pprof_timestamped_x1000 | execution_time | [944.276µs; 944.970µs] or [-0.037%; +0.037%] | None | None | None |
Group 2
| cpu_model | git_commit_sha | git_commit_date | git_branch |
|---|---|---|---|
| Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz | 0c6e2a5 | 1784223782 | main |
| scenario | metric | min | mean ± sd | median ± mad | p75 | p95 | p99 | max | peak_to_median_ratio | skewness | kurtosis | cv | sem | runs | sample_size |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| benching string interning on wordpress profile | execution_time | 113.218µs | 114.272µs ± 0.384µs | 114.252µs ± 0.125µs | 114.392µs | 114.714µs | 115.485µs | 117.054µs | 2.45% | 2.597 | 18.907 | 0.34% | 0.027µs | 1 | 200 |
| scenario | metric | 95% CI mean | Shapiro-Wilk pvalue | Ljung-Box pvalue (lag=1) | Dip test pvalue |
|---|---|---|---|---|---|
| benching string interning on wordpress profile | execution_time | [114.219µs; 114.325µs] or [-0.047%; +0.047%] | None | None | None |
Group 3
| cpu_model | git_commit_sha | git_commit_date | git_branch |
|---|---|---|---|
| Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz | 0c6e2a5 | 1784223782 | main |
| scenario | metric | min | mean ± sd | median ± mad | p75 | p95 | p99 | max | peak_to_median_ratio | skewness | kurtosis | cv | sem | runs | sample_size |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| profile_add_sample2_frames_x1000 | execution_time | 694.570µs | 695.661µs ± 0.402µs | 695.664µs ± 0.224µs | 695.884µs | 696.284µs | 696.854µs | 697.221µs | 0.22% | 0.134 | 1.512 | 0.06% | 0.028µs | 1 | 200 |
| scenario | metric | 95% CI mean | Shapiro-Wilk pvalue | Ljung-Box pvalue (lag=1) | Dip test pvalue |
|---|---|---|---|---|---|
| profile_add_sample2_frames_x1000 | execution_time | [695.605µs; 695.717µs] or [-0.008%; +0.008%] | None | None | None |
Group 4
| cpu_model | git_commit_sha | git_commit_date | git_branch |
|---|---|---|---|
| Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz | 0c6e2a5 | 1784223782 | main |
| scenario | metric | min | mean ± sd | median ± mad | p75 | p95 | p99 | max | peak_to_median_ratio | skewness | kurtosis | cv | sem | runs | sample_size |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| profile_add_sample_frames_x1000 | execution_time | 4.058ms | 4.063ms ± 0.002ms | 4.062ms ± 0.001ms | 4.063ms | 4.066ms | 4.069ms | 4.071ms | 0.21% | 1.141 | 1.971 | 0.05% | 0.000ms | 1 | 200 |
| scenario | metric | 95% CI mean | Shapiro-Wilk pvalue | Ljung-Box pvalue (lag=1) | Dip test pvalue |
|---|---|---|---|---|---|
| profile_add_sample_frames_x1000 | execution_time | [4.062ms; 4.063ms] or [-0.007%; +0.007%] | None | None | None |
Group 5
| cpu_model | git_commit_sha | git_commit_date | git_branch |
|---|---|---|---|
| Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz | 0c6e2a5 | 1784223782 | main |
| scenario | metric | min | mean ± sd | median ± mad | p75 | p95 | p99 | max | peak_to_median_ratio | skewness | kurtosis | cv | sem | runs | sample_size |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| profile_add_sample_timestamped_x1000 | execution_time | 4.063ms | 4.070ms ± 0.006ms | 4.069ms ± 0.002ms | 4.071ms | 4.074ms | 4.081ms | 4.150ms | 1.99% | 10.592 | 130.777 | 0.15% | 0.000ms | 1 | 200 |
| scenario | metric | 95% CI mean | Shapiro-Wilk pvalue | Ljung-Box pvalue (lag=1) | Dip test pvalue |
|---|---|---|---|---|---|
| profile_add_sample_timestamped_x1000 | execution_time | [4.069ms; 4.071ms] or [-0.021%; +0.021%] | None | None | None |
Group 6
| cpu_model | git_commit_sha | git_commit_date | git_branch |
|---|---|---|---|
| Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz | 0c6e2a5 | 1784223782 | main |
| scenario | metric | min | mean ± sd | median ± mad | p75 | p95 | p99 | max | peak_to_median_ratio | skewness | kurtosis | cv | sem | runs | sample_size |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| profiles_dictionary/profile_string_inserts/threads/1 | execution_time | 317.357µs | 320.468µs ± 1.904µs | 320.981µs ± 1.105µs | 321.868µs | 322.601µs | 322.873µs | 322.941µs | 0.61% | -0.435 | -1.168 | 0.56% | 0.602µs | 1 | 10 |
| profiles_dictionary/profile_string_inserts/threads/1 | throughput | 3170852.937op/s | 3195431.516op/s ± 19034.880op/s | 3190227.972op/s ± 10946.882op/s | 3210266.130op/s | 3223625.531op/s | 3226044.741op/s | 3226649.544op/s | 1.14% | 0.446 | -1.162 | 0.57% | 6019.358op/s | 1 | 10 |
| profiles_dictionary/profile_string_inserts/threads/16 | execution_time | 1.937ms | 1.956ms ± 0.009ms | 1.960ms ± 0.003ms | 1.962ms | 1.963ms | 1.964ms | 1.964ms | 0.21% | -1.334 | 0.581 | 0.42% | 0.003ms | 1 | 10 |
| profiles_dictionary/profile_string_inserts/threads/16 | throughput | 8342968.933op/s | 8374918.832op/s ± 37150.304op/s | 8360087.426op/s ± 14031.559op/s | 8381235.793op/s | 8440914.968op/s | 8455207.536op/s | 8458780.678op/s | 1.18% | 1.344 | 0.608 | 0.42% | 11747.958op/s | 1 | 10 |
| profiles_dictionary/profile_string_inserts/threads/2 | execution_time | 564.312µs | 566.898µs ± 1.387µs | 566.917µs ± 0.858µs | 567.914µs | 568.615µs | 568.909µs | 568.983µs | 0.36% | -0.382 | -0.500 | 0.23% | 0.439µs | 1 | 10 |
| profiles_dictionary/profile_string_inserts/threads/2 | throughput | 3599406.076op/s | 3612660.012op/s ± 8848.242op/s | 3612522.130op/s ± 5460.676op/s | 3615695.329op/s | 3626359.540op/s | 3628629.218op/s | 3629196.638op/s | 0.46% | 0.391 | -0.493 | 0.23% | 2798.060op/s | 1 | 10 |
| profiles_dictionary/profile_string_inserts/threads/4 | execution_time | 747.680µs | 752.302µs ± 3.305µs | 751.748µs ± 2.266µs | 755.059µs | 756.948µs | 757.197µs | 757.259µs | 0.73% | 0.254 | -1.211 | 0.42% | 1.045µs | 1 | 10 |
| profiles_dictionary/profile_string_inserts/threads/4 | throughput | 5408979.404op/s | 5444717.977op/s ± 23898.233op/s | 5448634.982op/s ± 16478.447op/s | 5459513.178op/s | 5474835.713op/s | 5477592.232op/s | 5478281.362op/s | 0.54% | -0.245 | -1.211 | 0.42% | 7557.285op/s | 1 | 10 |
| scenario | metric | 95% CI mean | Shapiro-Wilk pvalue | Ljung-Box pvalue (lag=1) | Dip test pvalue |
|---|---|---|---|---|---|
| profiles_dictionary/profile_string_inserts/threads/1 | execution_time | [319.287µs; 321.648µs] or [-0.368%; +0.368%] | None | None | None |
| profiles_dictionary/profile_string_inserts/threads/1 | throughput | [3183633.792op/s; 3207229.240op/s] or [-0.369%; +0.369%] | None | None | None |
| profiles_dictionary/profile_string_inserts/threads/16 | execution_time | [1.951ms; 1.962ms] or [-0.273%; +0.273%] | None | None | None |
| profiles_dictionary/profile_string_inserts/threads/16 | throughput | [8351893.258op/s; 8397944.406op/s] or [-0.275%; +0.275%] | None | None | None |
| profiles_dictionary/profile_string_inserts/threads/2 | execution_time | [566.039µs; 567.758µs] or [-0.152%; +0.152%] | None | None | None |
| profiles_dictionary/profile_string_inserts/threads/2 | throughput | [3607175.915op/s; 3618144.108op/s] or [-0.152%; +0.152%] | None | None | None |
| profiles_dictionary/profile_string_inserts/threads/4 | execution_time | [750.253µs; 754.351µs] or [-0.272%; +0.272%] | None | None | None |
| profiles_dictionary/profile_string_inserts/threads/4 | throughput | [5429905.971op/s; 5459529.983op/s] or [-0.272%; +0.272%] | None | None | None |
🎉 All green!🧪 All tests passed 🎯 Code Coverage (details) 🔗 Commit SHA: 6b4ba8c | Docs | Datadog PR Page | Give us feedback! |
Artifact Size Benchmark Reportaarch64-alpine-linux-musl
aarch64-unknown-linux-gnu
libdatadog-x64-windows
libdatadog-x86-windows
x86_64-alpine-linux-musl
x86_64-unknown-linux-gnu
|
2a80270 to
d9e28af
Compare
d9e28af to
6b4ba8c
Compare
What does this PR do?
Reduces the memory floor of the profiling
ProfilesDictionaryarena-backed storage by changing existing shard count and arena chunk size constants.Specifically:
ParallelSliceSet/ParallelStringSetshard count changes from 16 to 4.SliceSetarena size hint changes from 1 MiB to 256 KiB.Set<T>arena size hint changes from 1 MiB to 256 KiB, reducing the per-shard floor for function and mapping sets.N_SHARDSinstead of hardcoding a 4-bit mask.This changes the approximate
ProfilesDictionaryarena floor from:to:
No allocator APIs are added or changed in this PR.
Motivation
In Python profiling memory experiments, the profiles dictionary storage showed up as a meaningful virtual memory floor. The goal is to make the dictionary storage floor smaller by reducing the string shard multiplicity and reducing arena chunk sizes for strings, functions, and mappings.
This PR intentionally leaves the profile-local
StringTablechunk size unchanged. That can be evaluated separately if needed.Additional Notes
The main trade-off is potentially higher string insertion contention because the string set now has 4 shards instead of 16. For Python profiling, this should be acceptable, but we should validate with workload benchmarks and profile counts/sizes.
Function shards remain at 4. Mapping shards remain at 2. This PR only reduces their per-shard arena size.
How to test the change?
Ran:
cargo fmt cargo test -p libdd-profiling --libFinal result: