Enable performance analyzers for Datadog.Trace#8276
Conversation
37e4b3e to
aa429c3
Compare
BenchmarksBenchmark execution time: 2026-03-13 18:08:39 Comparing candidate commit 5c769bb in PR branch Found 6 performance improvements and 6 performance regressions! Performance is the same for 167 metrics, 13 unstable metrics. scenario:Benchmarks.Trace.AgentWriterBenchmark.WriteAndFlushEnrichedTraces netcoreapp3.1
scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.AllCycleMoreComplexBody net6.0
scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.ObjectExtractorMoreComplexBody netcoreapp3.1
scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.ObjectExtractorSimpleBody net6.0
scenario:Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces netcoreapp3.1
scenario:Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatBenchmark netcoreapp3.1
scenario:Benchmarks.Trace.SingleSpanAspNetCoreBenchmark.SingleSpanAspNetCore net6.0
scenario:Benchmarks.Trace.SingleSpanAspNetCoreBenchmark.SingleSpanAspNetCore netcoreapp3.1
scenario:Benchmarks.Trace.SpanBenchmark.StartFinishScope netcoreapp3.1
scenario:Benchmarks.Trace.SpanBenchmark.StartFinishTwoScopes netcoreapp3.1
|
Execution-Time Benchmarks Report ⏱️Execution-time results for samples comparing This PR (8276) and master. ✅ No regressions detected - check the details below Full Metrics ComparisonFakeDbCommand
HttpMessageHandler
Comparison explanationExecution-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 highlighted 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). Duration chartsFakeDbCommand (.NET Framework 4.8)gantt
title Execution time (ms) FakeDbCommand (.NET Framework 4.8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8276) - mean (76ms) : 74, 79
master - mean (76ms) : 74, 79
section Bailout
This PR (8276) - mean (81ms) : 79, 83
master - mean (81ms) : 78, 83
section CallTarget+Inlining+NGEN
This PR (8276) - mean (1,114ms) : 1073, 1155
master - mean (1,114ms) : 1073, 1155
FakeDbCommand (.NET Core 3.1)gantt
title Execution time (ms) FakeDbCommand (.NET Core 3.1)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8276) - mean (120ms) : 116, 124
master - mean (120ms) : 116, 124
section Bailout
This PR (8276) - mean (121ms) : 119, 124
master - mean (122ms) : 119, 126
section CallTarget+Inlining+NGEN
This PR (8276) - mean (769ms) : 747, 791
master - mean (775ms) : 751, 800
FakeDbCommand (.NET 6)gantt
title Execution time (ms) FakeDbCommand (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8276) - mean (107ms) : 103, 110
master - mean (107ms) : 103, 110
section Bailout
This PR (8276) - mean (108ms) : 105, 111
master - mean (109ms) : 106, 111
section CallTarget+Inlining+NGEN
This PR (8276) - mean (735ms) : 700, 770
master - mean (732ms) : 704, 760
FakeDbCommand (.NET 8)gantt
title Execution time (ms) FakeDbCommand (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8276) - mean (106ms) : 102, 110
master - mean (107ms) : 96, 118
section Bailout
This PR (8276) - mean (106ms) : 104, 109
master - mean (107ms) : 104, 109
section CallTarget+Inlining+NGEN
This PR (8276) - mean (672ms) : 651, 693
master - mean (673ms) : 654, 693
HttpMessageHandler (.NET Framework 4.8)gantt
title Execution time (ms) HttpMessageHandler (.NET Framework 4.8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8276) - mean (194ms) : 190, 198
master - mean (199ms) : 189, 210
section Bailout
This PR (8276) - mean (198ms) : 194, 201
master - mean (202ms) : 196, 208
section CallTarget+Inlining+NGEN
This PR (8276) - mean (1,152ms) : 1102, 1201
master - mean (1,166ms) : 1102, 1231
HttpMessageHandler (.NET Core 3.1)gantt
title Execution time (ms) HttpMessageHandler (.NET Core 3.1)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8276) - mean (279ms) : 273, 285
master - mean (281ms) : 273, 290
section Bailout
This PR (8276) - mean (280ms) : 272, 289
master - mean (283ms) : 273, 293
section CallTarget+Inlining+NGEN
This PR (8276) - mean (905ms) : 875, 936
master - mean (913ms) : 882, 943
HttpMessageHandler (.NET 6)gantt
title Execution time (ms) HttpMessageHandler (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8276) - mean (275ms) : 266, 283
master - mean (273ms) : 267, 279
section Bailout
This PR (8276) - mean (273ms) : 268, 278
master - mean (274ms) : 268, 281
section CallTarget+Inlining+NGEN
This PR (8276) - mean (913ms) : 890, 935
master - mean (921ms) : 895, 948
HttpMessageHandler (.NET 8)gantt
title Execution time (ms) HttpMessageHandler (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8276) - mean (276ms) : 266, 285
master - mean (279ms) : 271, 286
section Bailout
This PR (8276) - mean (272ms) : 264, 280
master - mean (280ms) : 272, 288
section CallTarget+Inlining+NGEN
This PR (8276) - mean (823ms) : 803, 842
master - mean (833ms) : 810, 856
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| })); | ||
|
|
||
| Log.Debug( | ||
| Log.Debug<int, string>( |
There was a problem hiding this comment.
unrelated fix, but it was calling the wrong overload previously!
74132e3 to
bf90963
Compare
bf90963 to
df58165
Compare
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…IfNull Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
c344219 to
5c769bb
Compare
| @@ -2,3 +2,67 @@ | |||
|
|
|||
| [*.{cs,vb}] | |||
| dotnet_diagnostic.DDSEAL001.severity = error # types should be sealed | |||
There was a problem hiding this comment.
This is not a change in this PR, but related. Should we replace the custom DDSEAL001 with CA1852?
There was a problem hiding this comment.
tl;dr; Nope 😄 They're basically the same - DDSEAL001 was essentially written as a clone of CA1852, but accounting for the subtleties of our codebase, i.e. we want to make all our types sealed, not just the internal ones.
…CA1850` (#8303) ## Summary of changes Enables the CA1850 analyzer, and fixes the two existing violations ## Reason for change The CA1850 analyzer says "use the static `MD5.HashData` instead of `MD5.Create()` etc. We need to use `#if` because it's only in .NET Core. However, in looking at the violations, I saw there was a big opportunity for allocation and speed improvements too, so did them together ## Implementation details - Added basic tests for existing code that was to be refactored - Create an `Md5Helper.ComputeMd5Hash()` method that takes a `string`, converts to UTF-8, and computes the hash, as efficiently as possibly (stackalloc where possible etc) - Update existing usages to use the new helper - "Fix" other allocatey paths that were using the hash output to be "better" 😄 ## Test coverage - Added some unit tests to ensure correctness. They're not extensive, but they're good enough I think - Ran some basic benchmarks, I think the results speak for themselves 😉 | Method | Runtime | Mean | Error | Allocated | | --------------------- | ------------------ | ---------: | -------: | --------: | | FeatureFlags_Original | .NET 10.0 | 632.3 ns | 5.64 ns | 1120 B | | FeatureFlags_Updated | .NET 10.0 | 204.4 ns | 3.78 ns | - | | FeatureFlags_Original | .NET 6.0 | 672.5 ns | 7.59 ns | 1112 B | | FeatureFlags_Updated | .NET 6.0 | 223.7 ns | 4.34 ns | - | | FeatureFlags_Original | .NET Core 2.1 | 1,102.5 ns | 21.09 ns | 1128 B | | FeatureFlags_Updated | .NET Core 2.1 | 565.7 ns | 9.12 ns | 208 B | | FeatureFlags_Original | .NET Core 3.1 | 899.9 ns | 17.84 ns | 1112 B | | FeatureFlags_Updated | .NET Core 3.1 | 366.3 ns | 7.26 ns | 128 B | | FeatureFlags_Original | .NET Framework 4.8 | 2,822.1 ns | 53.48 ns | 1444 B | | FeatureFlags_Updated | .NET Framework 4.8 | 1,861.8 ns | 36.68 ns | 522 B | | | | | | | | ToUUID_Original | .NET 10.0 | 860.4 ns | 17.27 ns | 1024 B | | ToUUID_Updated | .NET 10.0 | 333.6 ns | 5.05 ns | 96 B | | ToUUID_Original | .NET 6.0 | 815.5 ns | 14.31 ns | 1016 B | | ToUUID_Updated | .NET 6.0 | 365.3 ns | 2.66 ns | 96 B | | ToUUID_Original | .NET Core 2.1 | 1,055.6 ns | 20.77 ns | 1048 B | | ToUUID_Updated | .NET Core 2.1 | 733.5 ns | 13.69 ns | 408 B | | ToUUID_Original | .NET Core 3.1 | 876.6 ns | 13.99 ns | 1016 B | | ToUUID_Updated | .NET Core 3.1 | 498.1 ns | 9.36 ns | 224 B | | ToUUID_Original | .NET Framework 4.8 | 2,365.0 ns | 46.94 ns | 1484 B | | ToUUID_Updated | .NET Framework 4.8 | 2,305.9 ns | 45.79 ns | 722 B | ## Other details https://datadoghq.atlassian.net/browse/LANGPLAT-813 Stacked on other analyzer enablement tests: - #8276 (comment)
Summary of changes
Enables (most of) the performance rule analyzers
Reason for change
We should be following performance best-practices, and these are easy wins in most cases. In many cases, we don't have any violations. In some cases there are many violations 😅
Implementation details
I started doing this by hand, delegated the rest to 🤖, then reviewed them all (and fixed some more) by hand. Every commit handles a single analyzer
I strongly recommend reviewing commit-by-commit
There are basically 4 different types of commit:
Test coverage
All our current tests should cover these changes. The vast majority of the "fixes" are mechanical changes (have code fixes) so should be safe, but do keep your eye out.
Other details
https://datadoghq.atlassian.net/browse/LANGPLAT-813
Just to repeat, review this commit-by-commit, you'll have a much easier time 😄
Tip
Click on
Commitsabove, then use n and p to navigate between the commits