-
Notifications
You must be signed in to change notification settings - Fork 140
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
Add default value to StringBuilderCache, and use in more places #6232
Conversation
Datadog ReportBranch report: ✅ 0 Failed, 375637 Passed, 2715 Skipped, 26h 4m 47.12s Total Time |
Execution-Time Benchmarks Report ⏱️Execution-time results for samples comparing the following branches/commits: Execution-time benchmarks measure the whole time it takes to execute a program. And are intended to measure the one-off costs. Cases where the execution time results for the PR are worse than latest master results are shown in red. The following thresholds were used for comparing the execution times:
Note that these results are based on a single point-in-time result for each branch. For full results, see the dashboard. Graphs show the p99 interval based on the mean and StdDev of the test run, as well as the mean value of the run (shown as a diamond below the graph). gantt
title Execution time (ms) FakeDbCommand (.NET Framework 4.6.2)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6232) - mean (70ms) : 68, 72
. : milestone, 70,
master - mean (70ms) : 68, 71
. : milestone, 70,
section CallTarget+Inlining+NGEN
This PR (6232) - mean (1,115ms) : 1093, 1136
. : milestone, 1115,
master - mean (1,116ms) : 1099, 1133
. : milestone, 1116,
gantt
title Execution time (ms) FakeDbCommand (.NET Core 3.1)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6232) - mean (108ms) : 105, 110
. : milestone, 108,
master - mean (108ms) : 106, 110
. : milestone, 108,
section CallTarget+Inlining+NGEN
This PR (6232) - mean (776ms) : 762, 789
. : milestone, 776,
master - mean (775ms) : 762, 787
. : milestone, 775,
gantt
title Execution time (ms) FakeDbCommand (.NET 6)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6232) - mean (91ms) : 89, 94
. : milestone, 91,
master - mean (91ms) : 90, 93
. : milestone, 91,
section CallTarget+Inlining+NGEN
This PR (6232) - mean (733ms) : 715, 751
. : milestone, 733,
master - mean (731ms) : 716, 746
. : milestone, 731,
gantt
title Execution time (ms) HttpMessageHandler (.NET Framework 4.6.2)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6232) - mean (190ms) : 187, 192
. : milestone, 190,
master - mean (191ms) : 185, 196
. : milestone, 191,
section CallTarget+Inlining+NGEN
This PR (6232) - mean (1,226ms) : 1205, 1246
. : milestone, 1226,
master - mean (1,229ms) : 1208, 1250
. : milestone, 1229,
gantt
title Execution time (ms) HttpMessageHandler (.NET Core 3.1)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6232) - mean (276ms) : 272, 280
. : milestone, 276,
master - mean (275ms) : 270, 280
. : milestone, 275,
section CallTarget+Inlining+NGEN
This PR (6232) - mean (954ms) : 935, 972
. : milestone, 954,
master - mean (949ms) : 934, 964
. : milestone, 949,
gantt
title Execution time (ms) HttpMessageHandler (.NET 6)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6232) - mean (264ms) : 260, 269
. : milestone, 264,
master - mean (264ms) : 260, 268
. : milestone, 264,
section CallTarget+Inlining+NGEN
This PR (6232) - mean (943ms) : 915, 970
. : milestone, 943,
master - mean (935ms) : 913, 957
. : milestone, 935,
|
Benchmarks Report for appsec 🐌Benchmarks for #6232 compared to master:
The following thresholds were used for comparing the benchmark speeds:
Allocation changes below 0.5% are ignored. Benchmark detailsBenchmarks.Trace.Asm.AppSecBodyBenchmark - Faster 🎉 Same allocations ✔️
|
Benchmark | base/diff | Base Median (ns) | Diff Median (ns) | Modality |
---|---|---|---|---|
Benchmarks.Trace.Asm.AppSecBodyBenchmark.ObjectExtractorMoreComplexBody‑net472 | 1.158 | 4,358.01 | 3,763.55 |
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | AllCycleSimpleBody |
net6.0 | 72.3μs | 67.8ns | 263ns | 0.0716 | 0 | 0 | 6 KB |
master | AllCycleSimpleBody |
netcoreapp3.1 | 62.5μs | 58.7ns | 220ns | 0.0938 | 0 | 0 | 6.95 KB |
master | AllCycleSimpleBody |
net472 | 49.1μs | 72ns | 279ns | 1.31 | 0 | 0 | 8.33 KB |
master | AllCycleMoreComplexBody |
net6.0 | 78.4μs | 55ns | 213ns | 0.117 | 0 | 0 | 9.51 KB |
master | AllCycleMoreComplexBody |
netcoreapp3.1 | 69.4μs | 56.4ns | 211ns | 0.139 | 0 | 0 | 10.36 KB |
master | AllCycleMoreComplexBody |
net472 | 56.5μs | 85.2ns | 330ns | 1.87 | 0.0283 | 0 | 11.85 KB |
master | ObjectExtractorSimpleBody |
net6.0 | 145ns | 0.12ns | 0.448ns | 0.00395 | 0 | 0 | 280 B |
master | ObjectExtractorSimpleBody |
netcoreapp3.1 | 209ns | 0.137ns | 0.494ns | 0.00369 | 0 | 0 | 272 B |
master | ObjectExtractorSimpleBody |
net472 | 171ns | 0.0861ns | 0.334ns | 0.0446 | 0 | 0 | 281 B |
master | ObjectExtractorMoreComplexBody |
net6.0 | 3.04μs | 2.64ns | 9.86ns | 0.0533 | 0 | 0 | 3.78 KB |
master | ObjectExtractorMoreComplexBody |
netcoreapp3.1 | 3.91μs | 3.08ns | 11.9ns | 0.0507 | 0 | 0 | 3.69 KB |
master | ObjectExtractorMoreComplexBody |
net472 | 4.36μs | 1.92ns | 7.44ns | 0.601 | 0.00656 | 0 | 3.8 KB |
#6232 | AllCycleSimpleBody |
net6.0 | 73μs | 108ns | 416ns | 0.0739 | 0 | 0 | 6.01 KB |
#6232 | AllCycleSimpleBody |
netcoreapp3.1 | 62.7μs | 52.5ns | 203ns | 0.0934 | 0 | 0 | 6.95 KB |
#6232 | AllCycleSimpleBody |
net472 | 48.3μs | 38.7ns | 150ns | 1.31 | 0 | 0 | 8.33 KB |
#6232 | AllCycleMoreComplexBody |
net6.0 | 79.1μs | 55.9ns | 216ns | 0.119 | 0 | 0 | 9.51 KB |
#6232 | AllCycleMoreComplexBody |
netcoreapp3.1 | 69.2μs | 82.7ns | 309ns | 0.138 | 0 | 0 | 10.37 KB |
#6232 | AllCycleMoreComplexBody |
net472 | 54.6μs | 54ns | 209ns | 1.88 | 0.0273 | 0 | 11.85 KB |
#6232 | ObjectExtractorSimpleBody |
net6.0 | 140ns | 0.25ns | 0.969ns | 0.00398 | 0 | 0 | 280 B |
#6232 | ObjectExtractorSimpleBody |
netcoreapp3.1 | 207ns | 0.633ns | 2.45ns | 0.00362 | 0 | 0 | 272 B |
#6232 | ObjectExtractorSimpleBody |
net472 | 169ns | 0.145ns | 0.56ns | 0.0446 | 0 | 0 | 281 B |
#6232 | ObjectExtractorMoreComplexBody |
net6.0 | 3.17μs | 2.03ns | 7.59ns | 0.0527 | 0 | 0 | 3.78 KB |
#6232 | ObjectExtractorMoreComplexBody |
netcoreapp3.1 | 3.91μs | 2.15ns | 8.04ns | 0.049 | 0 | 0 | 3.69 KB |
#6232 | ObjectExtractorMoreComplexBody |
net472 | 3.76μs | 1.97ns | 7.64ns | 0.602 | 0.00566 | 0 | 3.8 KB |
Benchmarks.Trace.Asm.AppSecEncoderBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | EncodeArgs |
net6.0 | 38.2μs | 26.2ns | 102ns | 0.454 | 0 | 0 | 32.4 KB |
master | EncodeArgs |
netcoreapp3.1 | 54.3μs | 36.7ns | 142ns | 0.432 | 0 | 0 | 32.4 KB |
master | EncodeArgs |
net472 | 66.4μs | 27.9ns | 104ns | 5.15 | 0.0661 | 0 | 32.5 KB |
master | EncodeLegacyArgs |
net6.0 | 76.2μs | 407ns | 2.11μs | 0 | 0 | 0 | 2.14 KB |
master | EncodeLegacyArgs |
netcoreapp3.1 | 109μs | 254ns | 983ns | 0 | 0 | 0 | 2.14 KB |
master | EncodeLegacyArgs |
net472 | 154μs | 97.1ns | 376ns | 0.31 | 0 | 0 | 2.15 KB |
#6232 | EncodeArgs |
net6.0 | 37.1μs | 23.8ns | 92.1ns | 0.448 | 0 | 0 | 32.4 KB |
#6232 | EncodeArgs |
netcoreapp3.1 | 54.1μs | 32.9ns | 127ns | 0.433 | 0 | 0 | 32.4 KB |
#6232 | EncodeArgs |
net472 | 67.9μs | 38.5ns | 149ns | 5.16 | 0.0679 | 0 | 32.5 KB |
#6232 | EncodeLegacyArgs |
net6.0 | 80.4μs | 23.2ns | 86.8ns | 0 | 0 | 0 | 2.14 KB |
#6232 | EncodeLegacyArgs |
netcoreapp3.1 | 108μs | 64.1ns | 231ns | 0 | 0 | 0 | 2.14 KB |
#6232 | EncodeLegacyArgs |
net472 | 155μs | 98.6ns | 382ns | 0.31 | 0 | 0 | 2.15 KB |
Benchmarks.Trace.Asm.AppSecWafBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | RunWafRealisticBenchmark |
net6.0 | 185μs | 60.9ns | 236ns | 0 | 0 | 0 | 2.44 KB |
master | RunWafRealisticBenchmark |
netcoreapp3.1 | 198μs | 238ns | 921ns | 0 | 0 | 0 | 2.39 KB |
master | RunWafRealisticBenchmark |
net472 | 210μs | 141ns | 545ns | 0.315 | 0 | 0 | 2.46 KB |
master | RunWafRealisticBenchmarkWithAttack |
net6.0 | 122μs | 106ns | 381ns | 0 | 0 | 0 | 1.47 KB |
master | RunWafRealisticBenchmarkWithAttack |
netcoreapp3.1 | 130μs | 155ns | 598ns | 0 | 0 | 0 | 1.46 KB |
master | RunWafRealisticBenchmarkWithAttack |
net472 | 138μs | 42.5ns | 153ns | 0.208 | 0 | 0 | 1.49 KB |
#6232 | RunWafRealisticBenchmark |
net6.0 | 183μs | 91.5ns | 342ns | 0 | 0 | 0 | 2.44 KB |
#6232 | RunWafRealisticBenchmark |
netcoreapp3.1 | 196μs | 105ns | 380ns | 0 | 0 | 0 | 2.39 KB |
#6232 | RunWafRealisticBenchmark |
net472 | 210μs | 92.5ns | 346ns | 0.314 | 0 | 0 | 2.46 KB |
#6232 | RunWafRealisticBenchmarkWithAttack |
net6.0 | 123μs | 70.8ns | 274ns | 0 | 0 | 0 | 1.47 KB |
#6232 | RunWafRealisticBenchmarkWithAttack |
netcoreapp3.1 | 129μs | 68.9ns | 267ns | 0 | 0 | 0 | 1.46 KB |
#6232 | RunWafRealisticBenchmarkWithAttack |
net472 | 140μs | 49.5ns | 192ns | 0.209 | 0 | 0 | 1.49 KB |
Benchmarks.Trace.Iast.StringAspectsBenchmark - Same speed ✔️ More allocations ⚠️
More allocations ⚠️ in #6232
Benchmark
Base Allocated
Diff Allocated
Change
Change %
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑net472
272.91 KB
286.72 KB
13.81 KB
5.06%
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑net6.0
253.95 KB
264.78 KB
10.83 KB
4.27%
Fewer allocations 🎉 in #6232
Benchmark
Base Allocated
Diff Allocated
Change
Change %
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑netcoreapp3.1
255.27 KB
253.29 KB
-1.98 KB
-0.78%
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatBenchmark‑net472
60.49 KB
59.85 KB
-640 B
-1.06%
Benchmark | Base Allocated | Diff Allocated | Change | Change % |
---|---|---|---|---|
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑net472 | 272.91 KB | 286.72 KB | 13.81 KB | 5.06% |
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑net6.0 | 253.95 KB | 264.78 KB | 10.83 KB | 4.27% |
Benchmark | Base Allocated | Diff Allocated | Change | Change % |
---|---|---|---|---|
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark‑netcoreapp3.1 | 255.27 KB | 253.29 KB | -1.98 KB | -0.78% |
Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatBenchmark‑net472 | 60.49 KB | 59.85 KB | -640 B | -1.06% |
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | StringConcatBenchmark |
net6.0 | 52.9μs | 209ns | 782ns | 0 | 0 | 0 | 43.44 KB |
master | StringConcatBenchmark |
netcoreapp3.1 | 54.2μs | 287ns | 1.38μs | 0 | 0 | 0 | 42.64 KB |
master | StringConcatBenchmark |
net472 | 38μs | 165ns | 616ns | 0 | 0 | 0 | 60.49 KB |
master | StringConcatAspectBenchmark |
net6.0 | 295μs | 4.71μs | 43.7μs | 0 | 0 | 0 | 253.95 KB |
master | StringConcatAspectBenchmark |
netcoreapp3.1 | 354μs | 1.97μs | 12.1μs | 0 | 0 | 0 | 255.27 KB |
master | StringConcatAspectBenchmark |
net472 | 278μs | 6.14μs | 58.9μs | 0 | 0 | 0 | 272.91 KB |
#6232 | StringConcatBenchmark |
net6.0 | 60.6μs | 739ns | 7.2μs | 0 | 0 | 0 | 43.44 KB |
#6232 | StringConcatBenchmark |
netcoreapp3.1 | 55.3μs | 312ns | 2.1μs | 0 | 0 | 0 | 42.64 KB |
#6232 | StringConcatBenchmark |
net472 | 37.1μs | 56.8ns | 205ns | 0 | 0 | 0 | 59.85 KB |
#6232 | StringConcatAspectBenchmark |
net6.0 | 302μs | 6.1μs | 59.5μs | 0 | 0 | 0 | 264.78 KB |
#6232 | StringConcatAspectBenchmark |
netcoreapp3.1 | 338μs | 1.61μs | 6.23μs | 0 | 0 | 0 | 253.29 KB |
#6232 | StringConcatAspectBenchmark |
net472 | 254μs | 1.13μs | 4.39μs | 0 | 0 | 0 | 286.72 KB |
@@ -23,7 +23,7 @@ internal static class StringBuilderCache | |||
[ThreadStatic] | |||
private static StringBuilder? _cachedInstance; | |||
|
|||
public static StringBuilder Acquire(int capacity) | |||
public static StringBuilder Acquire(int capacity = MaxBuilderSize) |
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.
I wonder why we never had a default capacity here. Our StringBuilderCache
type was copied from based on .NET's internal StringBuilderCache
, and they had a 16
default capacity.
.NET Framework:
https://referencesource.microsoft.com/#mscorlib/system/text/stringbuildercache.cs,50
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.
yes, I wrote about this in the slack thread:
I'm not sure it makes a huge difference, since we're going to reuse that StringBuilder until it grows bigger that MaxBuilderSize, we might as well allocate it with that size from the get go
Either we needed less space and it gets reused, or we needed more, and in this case no harm in having a big one at first. It's only bad if we create stringbuilders that are too big in short lived threads where they won't get reused.
Where this creates trouble I think is when we use values like 256 that will get over the max allowed capacity when expanded (because the allocated memory doubles on expand, roughly), so if we request a StringBuilder of capacity 256 and we need to write 260 characters to it, it'll get thrown away on release, which is sad.
Which is why I think in our use case, 320 from the beginning is good.
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.
It can be wasteful to make the StringBuilder
default capacity either too small or too large. It's a trade-off between too much resizing (too small) or allocating more capacity than we need (too large). Some of that is mitigated by the fact that we reuse them to some extent, and I think we trend towards "larger is better, as long as it's not too large."
Unfortunately, it's all guesswork since we don't have the numbers to make an informed decision 😅. For example, how often are the StringBuilder
instances reused? How large do they get? What's the p50, p90, etc? How often do they grow above the max size? Does any of this have an impact large enough to justify adding telemetry? Am I overthinking this? 😝
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.
Yeah, I was thinking about this as well. We could add telemetry to it, on creation, on reuse and on release, and I think we'd have all the info we need. But I don't think it's something we do much. We do telemetry logs, but not really telemetry metrics ?
Because Microsoft chose 320 based on their experts' advice, but maybe we can choose a value more suited to our use cases. Also, as you say, it may be overthinking, and it may not matter that much in the end :p
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.
We do telemetry logs, but not really telemetry metrics ?
We have telemetry metrics. Usage is not very high because it's a newer feature and we haven't gone back to add it everywhere in older code.
See https://github.com/DataDog/dd-trace-dotnet/tree/master/tracer/src/Datadog.Trace/Telemetry/Metrics
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.
But I think there are issues with using "gauge" metrics (as opposed to "count"). @andrewlock is the expert there.
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.
gauge and count metrics are fine; distributions are not
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.
I don't see how this use case (StringBuilder
size) is different from the Baggage
size we were talking about earlier. I'm not a metrics expert, so I'm probably missing something.
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.
🤷♂️ it's not different AFAICT 😅 That has the same issues with distributions... Most likely we want a distribution here, not a gauge, so most likely we have the same problem 😄
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.
yes we'd probably like to have counters to evaluate the % of "cache miss", but also a distribution of the sizes. I didn't know distribution metrics were causing issues.
Benchmarks Report for tracer 🐌Benchmarks for #6232 compared to master:
The following thresholds were used for comparing the benchmark speeds:
Allocation changes below 0.5% are ignored. Benchmark detailsBenchmarks.Trace.ActivityBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.AgentWriterBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.AspNetCoreBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.DbCommandBenchmark - Faster 🎉 Same allocations ✔️
|
Benchmark | base/diff | Base Median (ns) | Diff Median (ns) | Modality |
---|---|---|---|---|
Benchmarks.Trace.DbCommandBenchmark.ExecuteNonQuery‑net6.0 | 1.118 | 1,378.17 | 1,233.03 |
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | ExecuteNonQuery |
net6.0 | 1.38μs | 1.33ns | 4.78ns | 0.0144 | 0 | 0 | 1.02 KB |
master | ExecuteNonQuery |
netcoreapp3.1 | 1.72μs | 1.45ns | 5.44ns | 0.0134 | 0 | 0 | 1.02 KB |
master | ExecuteNonQuery |
net472 | 2.11μs | 1.52ns | 5.68ns | 0.156 | 0.00105 | 0 | 987 B |
#6232 | ExecuteNonQuery |
net6.0 | 1.23μs | 0.805ns | 2.9ns | 0.0142 | 0 | 0 | 1.02 KB |
#6232 | ExecuteNonQuery |
netcoreapp3.1 | 1.72μs | 1.07ns | 3.87ns | 0.0139 | 0 | 0 | 1.02 KB |
#6232 | ExecuteNonQuery |
net472 | 2.12μs | 3.25ns | 12.6ns | 0.156 | 0.00106 | 0 | 987 B |
Benchmarks.Trace.ElasticsearchBenchmark - Faster 🎉 Same allocations ✔️
Faster 🎉 in #6232
Benchmark
base/diff
Base Median (ns)
Diff Median (ns)
Modality
Benchmarks.Trace.ElasticsearchBenchmark.CallElasticsearch‑net6.0
1.164
1,374.66
1,180.98
Benchmark | base/diff | Base Median (ns) | Diff Median (ns) | Modality |
---|---|---|---|---|
Benchmarks.Trace.ElasticsearchBenchmark.CallElasticsearch‑net6.0 | 1.164 | 1,374.66 | 1,180.98 |
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | CallElasticsearch |
net6.0 | 1.37μs | 1.93ns | 7.48ns | 0.0136 | 0 | 0 | 976 B |
master | CallElasticsearch |
netcoreapp3.1 | 1.51μs | 0.541ns | 1.95ns | 0.0129 | 0 | 0 | 976 B |
master | CallElasticsearch |
net472 | 2.51μs | 1.83ns | 7.11ns | 0.157 | 0 | 0 | 995 B |
master | CallElasticsearchAsync |
net6.0 | 1.44μs | 0.643ns | 2.49ns | 0.0131 | 0 | 0 | 952 B |
master | CallElasticsearchAsync |
netcoreapp3.1 | 1.65μs | 0.695ns | 2.6ns | 0.0137 | 0 | 0 | 1.02 KB |
master | CallElasticsearchAsync |
net472 | 2.54μs | 0.708ns | 2.74ns | 0.167 | 0 | 0 | 1.05 KB |
#6232 | CallElasticsearch |
net6.0 | 1.18μs | 3.4ns | 13.2ns | 0.0135 | 0 | 0 | 976 B |
#6232 | CallElasticsearch |
netcoreapp3.1 | 1.53μs | 0.43ns | 1.55ns | 0.0132 | 0 | 0 | 976 B |
#6232 | CallElasticsearch |
net472 | 2.71μs | 9.93ns | 38.5ns | 0.157 | 0 | 0 | 995 B |
#6232 | CallElasticsearchAsync |
net6.0 | 1.33μs | 0.839ns | 3.25ns | 0.0133 | 0 | 0 | 952 B |
#6232 | CallElasticsearchAsync |
netcoreapp3.1 | 1.71μs | 1.05ns | 4.06ns | 0.0137 | 0 | 0 | 1.02 KB |
#6232 | CallElasticsearchAsync |
net472 | 2.68μs | 6.2ns | 22.3ns | 0.166 | 0 | 0 | 1.05 KB |
Benchmarks.Trace.GraphQLBenchmark - Slower ⚠️ Same allocations ✔️
Slower ⚠️ in #6232
Benchmark
diff/base
Base Median (ns)
Diff Median (ns)
Modality
Benchmarks.Trace.GraphQLBenchmark.ExecuteAsync‑net6.0
1.148
1,132.20
1,300.01
Benchmark | diff/base | Base Median (ns) | Diff Median (ns) | Modality |
---|---|---|---|---|
Benchmarks.Trace.GraphQLBenchmark.ExecuteAsync‑net6.0 | 1.148 | 1,132.20 | 1,300.01 |
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | ExecuteAsync |
net6.0 | 1.13μs | 0.481ns | 1.86ns | 0.0131 | 0 | 0 | 952 B |
master | ExecuteAsync |
netcoreapp3.1 | 1.67μs | 0.376ns | 1.3ns | 0.0124 | 0 | 0 | 952 B |
master | ExecuteAsync |
net472 | 1.79μs | 1.6ns | 5.54ns | 0.145 | 0 | 0 | 915 B |
#6232 | ExecuteAsync |
net6.0 | 1.3μs | 0.615ns | 2.3ns | 0.0137 | 0 | 0 | 952 B |
#6232 | ExecuteAsync |
netcoreapp3.1 | 1.6μs | 1.62ns | 5.85ns | 0.0128 | 0 | 0 | 952 B |
#6232 | ExecuteAsync |
net472 | 1.81μs | 0.743ns | 2.78ns | 0.145 | 0 | 0 | 915 B |
Benchmarks.Trace.HttpClientBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | SendAsync |
net6.0 | 4.41μs | 2.68ns | 10ns | 0.0329 | 0 | 0 | 2.31 KB |
master | SendAsync |
netcoreapp3.1 | 5.27μs | 1.8ns | 6.74ns | 0.037 | 0 | 0 | 2.85 KB |
master | SendAsync |
net472 | 7.42μs | 3.7ns | 13.8ns | 0.493 | 0 | 0 | 3.12 KB |
#6232 | SendAsync |
net6.0 | 4.38μs | 2.58ns | 9.64ns | 0.0308 | 0 | 0 | 2.31 KB |
#6232 | SendAsync |
netcoreapp3.1 | 5.27μs | 1.7ns | 6.59ns | 0.0368 | 0 | 0 | 2.85 KB |
#6232 | SendAsync |
net472 | 7.59μs | 2.56ns | 9.56ns | 0.492 | 0 | 0 | 3.12 KB |
Benchmarks.Trace.ILoggerBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | EnrichedLog |
net6.0 | 1.59μs | 5.07ns | 19.6ns | 0.0233 | 0 | 0 | 1.64 KB |
master | EnrichedLog |
netcoreapp3.1 | 2.14μs | 1.24ns | 4.81ns | 0.0224 | 0 | 0 | 1.64 KB |
master | EnrichedLog |
net472 | 2.48μs | 1.68ns | 6.51ns | 0.25 | 0 | 0 | 1.57 KB |
#6232 | EnrichedLog |
net6.0 | 1.53μs | 1.27ns | 4.93ns | 0.0229 | 0 | 0 | 1.64 KB |
#6232 | EnrichedLog |
netcoreapp3.1 | 2.23μs | 0.678ns | 2.54ns | 0.0223 | 0 | 0 | 1.64 KB |
#6232 | EnrichedLog |
net472 | 2.64μs | 0.972ns | 3.77ns | 0.249 | 0 | 0 | 1.57 KB |
Benchmarks.Trace.Log4netBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | EnrichedLog |
net6.0 | 120μs | 174ns | 675ns | 0.0601 | 0 | 0 | 4.28 KB |
master | EnrichedLog |
netcoreapp3.1 | 120μs | 191ns | 741ns | 0 | 0 | 0 | 4.28 KB |
master | EnrichedLog |
net472 | 151μs | 210ns | 787ns | 0.678 | 0.226 | 0 | 4.46 KB |
#6232 | EnrichedLog |
net6.0 | 118μs | 138ns | 516ns | 0.0581 | 0 | 0 | 4.28 KB |
#6232 | EnrichedLog |
netcoreapp3.1 | 123μs | 242ns | 937ns | 0.0616 | 0 | 0 | 4.28 KB |
#6232 | EnrichedLog |
net472 | 153μs | 106ns | 397ns | 0.686 | 0.229 | 0 | 4.46 KB |
Benchmarks.Trace.NLogBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | EnrichedLog |
net6.0 | 3.16μs | 0.709ns | 2.75ns | 0.0316 | 0 | 0 | 2.2 KB |
master | EnrichedLog |
netcoreapp3.1 | 4.13μs | 0.543ns | 1.96ns | 0.0308 | 0 | 0 | 2.2 KB |
master | EnrichedLog |
net472 | 4.94μs | 1.55ns | 5.99ns | 0.319 | 0 | 0 | 2.02 KB |
#6232 | EnrichedLog |
net6.0 | 2.92μs | 0.862ns | 3.23ns | 0.0307 | 0 | 0 | 2.2 KB |
#6232 | EnrichedLog |
netcoreapp3.1 | 4.07μs | 1.36ns | 5.27ns | 0.0284 | 0 | 0 | 2.2 KB |
#6232 | EnrichedLog |
net472 | 4.94μs | 1.53ns | 5.72ns | 0.319 | 0 | 0 | 2.02 KB |
Benchmarks.Trace.RedisBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | SendReceive |
net6.0 | 1.33μs | 0.356ns | 1.33ns | 0.0159 | 0 | 0 | 1.14 KB |
master | SendReceive |
netcoreapp3.1 | 1.72μs | 0.584ns | 2.11ns | 0.0146 | 0 | 0 | 1.14 KB |
master | SendReceive |
net472 | 2.05μs | 0.847ns | 3.06ns | 0.184 | 0 | 0 | 1.16 KB |
#6232 | SendReceive |
net6.0 | 1.39μs | 1.14ns | 4.12ns | 0.0159 | 0 | 0 | 1.14 KB |
#6232 | SendReceive |
netcoreapp3.1 | 1.74μs | 0.935ns | 3.5ns | 0.0158 | 0 | 0 | 1.14 KB |
#6232 | SendReceive |
net472 | 2.14μs | 1.09ns | 4.23ns | 0.183 | 0 | 0 | 1.16 KB |
Benchmarks.Trace.SerilogBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | EnrichedLog |
net6.0 | 2.74μs | 1.15ns | 4.46ns | 0.0218 | 0 | 0 | 1.6 KB |
master | EnrichedLog |
netcoreapp3.1 | 3.94μs | 2.75ns | 10.3ns | 0.0217 | 0 | 0 | 1.65 KB |
master | EnrichedLog |
net472 | 4.46μs | 2.48ns | 9.27ns | 0.322 | 0 | 0 | 2.04 KB |
#6232 | EnrichedLog |
net6.0 | 2.85μs | 6.87ns | 26.6ns | 0.0225 | 0 | 0 | 1.6 KB |
#6232 | EnrichedLog |
netcoreapp3.1 | 3.85μs | 1.9ns | 7.34ns | 0.0212 | 0 | 0 | 1.65 KB |
#6232 | EnrichedLog |
net472 | 4.31μs | 1.54ns | 5.76ns | 0.323 | 0 | 0 | 2.04 KB |
Benchmarks.Trace.SpanBenchmark - Faster 🎉 Same allocations ✔️
Faster 🎉 in #6232
Benchmark
base/diff
Base Median (ns)
Diff Median (ns)
Modality
Benchmarks.Trace.SpanBenchmark.StartFinishSpan‑netcoreapp3.1
1.209
667.15
551.73
Benchmarks.Trace.SpanBenchmark.StartFinishSpan‑net6.0
1.179
473.26
401.24
Benchmark | base/diff | Base Median (ns) | Diff Median (ns) | Modality |
---|---|---|---|---|
Benchmarks.Trace.SpanBenchmark.StartFinishSpan‑netcoreapp3.1 | 1.209 | 667.15 | 551.73 | |
Benchmarks.Trace.SpanBenchmark.StartFinishSpan‑net6.0 | 1.179 | 473.26 | 401.24 |
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | StartFinishSpan |
net6.0 | 473ns | 0.421ns | 1.57ns | 0.0081 | 0 | 0 | 576 B |
master | StartFinishSpan |
netcoreapp3.1 | 664ns | 2.41ns | 9.32ns | 0.0075 | 0 | 0 | 576 B |
master | StartFinishSpan |
net472 | 720ns | 0.797ns | 3.09ns | 0.0915 | 0 | 0 | 578 B |
master | StartFinishScope |
net6.0 | 522ns | 0.457ns | 1.77ns | 0.00978 | 0 | 0 | 696 B |
master | StartFinishScope |
netcoreapp3.1 | 765ns | 0.641ns | 2.48ns | 0.00916 | 0 | 0 | 696 B |
master | StartFinishScope |
net472 | 906ns | 0.849ns | 3.29ns | 0.104 | 0 | 0 | 658 B |
#6232 | StartFinishSpan |
net6.0 | 401ns | 0.817ns | 3.16ns | 0.00803 | 0 | 0 | 576 B |
#6232 | StartFinishSpan |
netcoreapp3.1 | 552ns | 0.497ns | 1.86ns | 0.00761 | 0 | 0 | 576 B |
#6232 | StartFinishSpan |
net472 | 665ns | 0.815ns | 3.16ns | 0.0916 | 0 | 0 | 578 B |
#6232 | StartFinishScope |
net6.0 | 493ns | 0.452ns | 1.75ns | 0.00983 | 0 | 0 | 696 B |
#6232 | StartFinishScope |
netcoreapp3.1 | 754ns | 0.574ns | 2.22ns | 0.00942 | 0 | 0 | 696 B |
#6232 | StartFinishScope |
net472 | 863ns | 1.23ns | 4.78ns | 0.104 | 0 | 0 | 658 B |
Benchmarks.Trace.TraceAnnotationsBenchmark - Faster 🎉 Same allocations ✔️
Faster 🎉 in #6232
Benchmark
base/diff
Base Median (ns)
Diff Median (ns)
Modality
Benchmarks.Trace.TraceAnnotationsBenchmark.RunOnMethodBegin‑net6.0
1.130
730.85
646.98
Benchmark | base/diff | Base Median (ns) | Diff Median (ns) | Modality |
---|---|---|---|---|
Benchmarks.Trace.TraceAnnotationsBenchmark.RunOnMethodBegin‑net6.0 | 1.130 | 730.85 | 646.98 |
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | RunOnMethodBegin |
net6.0 | 731ns | 0.424ns | 1.59ns | 0.00951 | 0 | 0 | 696 B |
master | RunOnMethodBegin |
netcoreapp3.1 | 977ns | 1.19ns | 4.59ns | 0.00928 | 0 | 0 | 696 B |
master | RunOnMethodBegin |
net472 | 1.15μs | 1.61ns | 6.23ns | 0.104 | 0 | 0 | 658 B |
#6232 | RunOnMethodBegin |
net6.0 | 648ns | 0.701ns | 2.72ns | 0.00974 | 0 | 0 | 696 B |
#6232 | RunOnMethodBegin |
netcoreapp3.1 | 908ns | 4.8ns | 25ns | 0.00949 | 0 | 0 | 696 B |
#6232 | RunOnMethodBegin |
net472 | 1.16μs | 1.49ns | 5.76ns | 0.104 | 0 | 0 | 658 B |
Throughput/Crank Report ⚡Throughput results for AspNetCoreSimpleController comparing the following branches/commits: Cases where throughput results for the PR are worse than latest master (5% drop or greater), results are shown in red. Note that these results are based on a single point-in-time result for each branch. For full results, see one of the many, many dashboards! gantt
title Throughput Linux x64 (Total requests)
dateFormat X
axisFormat %s
section Baseline
This PR (6232) (11.149M) : 0, 11148809
master (11.132M) : 0, 11131684
benchmarks/2.9.0 (11.033M) : 0, 11032866
section Automatic
This PR (6232) (7.270M) : 0, 7270328
master (7.202M) : 0, 7202253
benchmarks/2.9.0 (7.786M) : 0, 7785853
section Trace stats
master (7.442M) : 0, 7442024
section Manual
master (10.983M) : 0, 10982660
section Manual + Automatic
This PR (6232) (6.737M) : 0, 6737264
master (6.645M) : 0, 6644995
section DD_TRACE_ENABLED=0
master (10.234M) : 0, 10233674
gantt
title Throughput Linux arm64 (Total requests)
dateFormat X
axisFormat %s
section Baseline
This PR (6232) (9.288M) : 0, 9287708
master (9.505M) : 0, 9505311
benchmarks/2.9.0 (9.495M) : 0, 9494821
section Automatic
This PR (6232) (6.468M) : 0, 6468079
master (6.463M) : 0, 6462996
section Trace stats
master (6.709M) : 0, 6709463
section Manual
master (9.346M) : 0, 9345687
section Manual + Automatic
This PR (6232) (5.796M) : 0, 5796330
master (5.903M) : 0, 5902776
section DD_TRACE_ENABLED=0
master (8.956M) : 0, 8956040
gantt
title Throughput Windows x64 (Total requests)
dateFormat X
axisFormat %s
section Baseline
This PR (6232) (9.357M) : 0, 9356773
master (9.708M) : 0, 9708001
benchmarks/2.9.0 (10.020M) : 0, 10019592
section Automatic
This PR (6232) (6.146M) : 0, 6146435
master (6.407M) : 0, 6407146
benchmarks/2.9.0 (7.255M) : 0, 7255257
section Trace stats
master (7.103M) : 0, 7102656
section Manual
master (9.685M) : 0, 9685116
section Manual + Automatic
This PR (6232) (5.593M) : crit ,0, 5592622
master (6.028M) : 0, 6027641
section DD_TRACE_ENABLED=0
master (9.212M) : 0, 9211970
|
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.
Thanks!
Summary of changes
StringBuilderCache.Acquire()
method. Since we're going to reuse it if it didn't grow, it's ok to allocate it a bit larger than we need by default.new StringBuilder
, and replaced with the cache where it made sense.Reason for change
Implementation details
Test coverage