Skip to content

Filter more dynamic assemblies#8120

Merged
bouwkast merged 2 commits intomasterfrom
steven/filter-more-assemblies
Feb 5, 2026
Merged

Filter more dynamic assemblies#8120
bouwkast merged 2 commits intomasterfrom
steven/filter-more-assemblies

Conversation

@bouwkast
Copy link
Collaborator

@bouwkast bouwkast commented Jan 30, 2026

Summary of changes

This filters out more dynamic assemblies that we don't want to send to telemetry due to cardinality issues. The main
additions are:

  • 10 hex character assembly names (e.g., a43d8b99ea)
  • dynamicclasses pattern (e.g., dynamicclasses254)

Both patterns only apply to assemblies with version 0.0.0.0.

Reason for change

Our telemetry is still sending a lot of dynamically generated assemblies. The backend is being updated to filter these out, but we should avoid sending them in the first place to reduce payload size and processing overhead.

From doing some manual testing these can slip by our IsDynamic check via:

Implementation details

Extended IsZeroVersionAssemblyPattern in DependencyTelemetryCollector to recognize two additional patterns:

  • 10 hex chars: Reuses existing IsHexString helper (already used for 32+ hex char filtering)
  • dynamicclasses: New IsDynamicClassesPattern method that checks for the literal lowercase prefix followed by
    one or more digits

Both checks use the character-by-character comparison.

Test coverage

Updated the tests to check for the new cases

Other details

Followed the existing design where we do the length and character-by-character comparison, unsure how scalable / maintainable / overhead this is, I guess it isn't too bad, but am a little concerned just tacking more stuff on here.

@bouwkast bouwkast added the AI Generated Largely based on code generated by an AI or LLM. This label is the same across all dd-trace-* repos label Jan 30, 2026
@pr-commenter
Copy link

pr-commenter bot commented Jan 30, 2026

Benchmarks

Benchmark execution time: 2026-02-02 15:47:43

Comparing candidate commit 4bf2896 in PR branch steven/filter-more-assemblies with baseline commit 8195b98 in branch master.

Found 14 performance improvements and 3 performance regressions! Performance is the same for 160 metrics, 15 unstable metrics.

scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.ObjectExtractorSimpleBody net472

  • 🟩 throughput [+409936.026op/s; +416990.161op/s] or [+14.020%; +14.261%]

scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.ObjectExtractorSimpleBody net6.0

  • 🟥 execution_time [+16.132ms; +22.511ms] or [+8.018%; +11.189%]

scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.ObjectExtractorSimpleBody netcoreapp3.1

  • 🟩 execution_time [-20.042ms; -14.254ms] or [-9.283%; -6.602%]

scenario:Benchmarks.Trace.AspNetCoreBenchmark.SendRequest netcoreapp3.1

  • 🟩 throughput [+497.803op/s; +1414.185op/s] or [+5.358%; +15.221%]

scenario:Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces net6.0

  • 🟥 execution_time [+17.506ms; +20.816ms] or [+10.556%; +12.552%]
  • 🟥 throughput [-175.217op/s; -145.526op/s] or [-11.347%; -9.424%]

scenario:Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSlice net6.0

  • 🟩 execution_time [-88.629µs; -81.917µs] or [-5.896%; -5.450%]
  • 🟩 throughput [+38.386op/s; +41.647op/s] or [+5.770%; +6.260%]

scenario:Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSliceWithPool net6.0

  • 🟩 execution_time [-86.095µs; -80.225µs] or [-7.705%; -7.180%]
  • 🟩 throughput [+69.378op/s; +74.572op/s] or [+7.752%; +8.332%]

scenario:Benchmarks.Trace.ElasticsearchBenchmark.CallElasticsearch net6.0

  • 🟩 execution_time [-15.718ms; -10.992ms] or [-7.362%; -5.149%]

scenario:Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark net6.0

  • 🟩 execution_time [-830.597µs; -732.470µs] or [-62.459%; -55.080%]

scenario:Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatBenchmark net6.0

  • 🟩 execution_time [-9.248µs; -4.844µs] or [-18.585%; -9.734%]
  • 🟩 throughput [+2077.321op/s; +3700.091op/s] or [+10.078%; +17.951%]

scenario:Benchmarks.Trace.RedisBenchmark.SendReceive netcoreapp3.1

  • 🟩 throughput [+20950.587op/s; +30331.100op/s] or [+5.436%; +7.870%]

scenario:Benchmarks.Trace.SerilogBenchmark.EnrichedLog net472

  • 🟩 throughput [+8222.620op/s; +9228.858op/s] or [+5.636%; +6.326%]

scenario:Benchmarks.Trace.SingleSpanAspNetCoreBenchmark.SingleSpanAspNetCore net6.0

  • 🟩 execution_time [-92.142ms; -76.579ms] or [-53.891%; -44.789%]

@dd-trace-dotnet-ci-bot
Copy link

dd-trace-dotnet-ci-bot bot commented Jan 30, 2026

Execution-Time Benchmarks Report ⏱️

Execution-time results for samples comparing This PR (8120) and master.

✅ No regressions detected - check the details below

Full Metrics Comparison

FakeDbCommand

Metric Master (Mean ± 95% CI) Current (Mean ± 95% CI) Change Status
.NET Framework 4.8 - Baseline
duration79.57 ± (79.42 - 79.74) ms79.71 ± (79.68 - 80.06) ms+0.2%✅⬆️
.NET Framework 4.8 - Bailout
duration84.02 ± (83.87 - 84.27) ms84.14 ± (83.95 - 84.41) ms+0.1%✅⬆️
.NET Framework 4.8 - CallTarget+Inlining+NGEN
duration1110.70 ± (1112.55 - 1118.94) ms1118.66 ± (1119.00 - 1126.89) ms+0.7%✅⬆️
.NET Core 3.1 - Baseline
process.internal_duration_ms24.41 ± (24.35 - 24.46) ms24.37 ± (24.32 - 24.42) ms-0.1%
process.time_to_main_ms94.89 ± (94.69 - 95.08) ms94.55 ± (94.33 - 94.77) ms-0.4%
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed10.90 ± (10.90 - 10.90) MB10.90 ± (10.89 - 10.90) MB-0.0%
runtime.dotnet.threads.count12 ± (12 - 12)12 ± (12 - 12)+0.0%
.NET Core 3.1 - Bailout
process.internal_duration_ms24.32 ± (24.25 - 24.39) ms24.27 ± (24.21 - 24.33) ms-0.2%
process.time_to_main_ms96.13 ± (95.89 - 96.36) ms95.49 ± (95.26 - 95.73) ms-0.7%
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed10.94 ± (10.93 - 10.94) MB10.93 ± (10.92 - 10.93) MB-0.1%
runtime.dotnet.threads.count13 ± (13 - 13)13 ± (13 - 13)+0.0%
.NET Core 3.1 - CallTarget+Inlining+NGEN
process.internal_duration_ms232.43 ± (229.53 - 235.34) ms234.51 ± (231.21 - 237.81) ms+0.9%✅⬆️
process.time_to_main_ms534.34 ± (533.40 - 535.27) ms536.49 ± (535.64 - 537.34) ms+0.4%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed48.53 ± (48.51 - 48.55) MB48.46 ± (48.43 - 48.48) MB-0.1%
runtime.dotnet.threads.count28 ± (28 - 28)28 ± (28 - 28)+0.0%
.NET 6 - Baseline
process.internal_duration_ms22.71 ± (22.66 - 22.77) ms22.87 ± (22.82 - 22.91) ms+0.7%✅⬆️
process.time_to_main_ms80.64 ± (80.42 - 80.86) ms81.32 ± (81.14 - 81.51) ms+0.8%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed10.62 ± (10.61 - 10.62) MB10.64 ± (10.63 - 10.64) MB+0.2%✅⬆️
runtime.dotnet.threads.count10 ± (10 - 10)10 ± (10 - 10)+0.0%
.NET 6 - Bailout
process.internal_duration_ms22.55 ± (22.49 - 22.62) ms22.89 ± (22.84 - 22.95) ms+1.5%✅⬆️
process.time_to_main_ms81.83 ± (81.61 - 82.04) ms82.69 ± (82.49 - 82.89) ms+1.1%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed10.77 ± (10.76 - 10.79) MB10.74 ± (10.73 - 10.75) MB-0.3%
runtime.dotnet.threads.count11 ± (11 - 11)11 ± (11 - 11)+0.0%
.NET 6 - CallTarget+Inlining+NGEN
process.internal_duration_ms232.22 ± (228.42 - 236.01) ms228.79 ± (225.08 - 232.49) ms-1.5%
process.time_to_main_ms504.98 ± (504.15 - 505.80) ms509.94 ± (509.05 - 510.82) ms+1.0%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed49.20 ± (49.18 - 49.22) MB49.16 ± (49.14 - 49.18) MB-0.1%
runtime.dotnet.threads.count28 ± (28 - 28)28 ± (28 - 28)-0.0%
.NET 8 - Baseline
process.internal_duration_ms20.77 ± (20.72 - 20.82) ms20.96 ± (20.91 - 21.01) ms+0.9%✅⬆️
process.time_to_main_ms79.46 ± (79.27 - 79.64) ms79.93 ± (79.74 - 80.12) ms+0.6%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed7.64 ± (7.64 - 7.65) MB7.65 ± (7.65 - 7.65) MB+0.1%✅⬆️
runtime.dotnet.threads.count10 ± (10 - 10)10 ± (10 - 10)+0.0%
.NET 8 - Bailout
process.internal_duration_ms20.71 ± (20.64 - 20.77) ms20.92 ± (20.86 - 20.98) ms+1.0%✅⬆️
process.time_to_main_ms80.40 ± (80.21 - 80.60) ms81.01 ± (80.78 - 81.24) ms+0.8%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed7.72 ± (7.71 - 7.73) MB7.72 ± (7.71 - 7.73) MB+0.0%✅⬆️
runtime.dotnet.threads.count11 ± (11 - 11)11 ± (11 - 11)+0.0%
.NET 8 - CallTarget+Inlining+NGEN
process.internal_duration_ms198.15 ± (197.44 - 198.85) ms202.56 ± (201.65 - 203.46) ms+2.2%✅⬆️
process.time_to_main_ms486.05 ± (484.93 - 487.17) ms491.93 ± (490.93 - 492.93) ms+1.2%✅⬆️
runtime.dotnet.exceptions.count0 ± (0 - 0)0 ± (0 - 0)+0.0%
runtime.dotnet.mem.committed36.98 ± (36.94 - 37.03) MB37.09 ± (37.06 - 37.12) MB+0.3%✅⬆️
runtime.dotnet.threads.count27 ± (27 - 27)27 ± (27 - 27)-0.1%

HttpMessageHandler

Metric Master (Mean ± 95% CI) Current (Mean ± 95% CI) Change Status
.NET Framework 4.8 - Baseline
duration210.41 ± (209.98 - 211.36) ms211.31 ± (212.18 - 214.14) ms+0.4%✅⬆️
.NET Framework 4.8 - Bailout
duration222.84 ± (221.96 - 223.76) ms216.45 ± (216.79 - 218.63) ms-2.9%
.NET Framework 4.8 - CallTarget+Inlining+NGEN
duration1217.94 ± (1218.05 - 1228.95) ms1233.33 ± (1233.80 - 1249.19) ms+1.3%✅⬆️
.NET Core 3.1 - Baseline
process.internal_duration_ms204.47 ± (203.84 - 205.10) ms207.03 ± (206.02 - 208.05) ms+1.3%✅⬆️
process.time_to_main_ms87.57 ± (87.28 - 87.85) ms89.27 ± (88.78 - 89.76) ms+1.9%✅⬆️
runtime.dotnet.exceptions.count3 ± (3 - 3)3 ± (3 - 3)+0.0%
runtime.dotnet.mem.committed15.91 ± (15.89 - 15.93) MB15.98 ± (15.96 - 15.99) MB+0.4%✅⬆️
runtime.dotnet.threads.count20 ± (20 - 20)20 ± (20 - 20)+0.0%✅⬆️
.NET Core 3.1 - Bailout
process.internal_duration_ms203.96 ± (203.24 - 204.67) ms210.95 ± (209.66 - 212.25) ms+3.4%✅⬆️
process.time_to_main_ms88.84 ± (88.61 - 89.06) ms91.05 ± (90.68 - 91.43) ms+2.5%✅⬆️
runtime.dotnet.exceptions.count3 ± (3 - 3)3 ± (3 - 3)+0.0%
runtime.dotnet.mem.committed15.97 ± (15.96 - 15.99) MB15.91 ± (15.89 - 15.93) MB-0.4%
runtime.dotnet.threads.count21 ± (21 - 21)21 ± (21 - 21)+0.2%✅⬆️
.NET Core 3.1 - CallTarget+Inlining+NGEN
process.internal_duration_ms430.29 ± (426.92 - 433.65) ms436.65 ± (433.15 - 440.16) ms+1.5%✅⬆️
process.time_to_main_ms510.96 ± (509.83 - 512.09) ms511.81 ± (510.73 - 512.89) ms+0.2%✅⬆️
runtime.dotnet.exceptions.count3 ± (3 - 3)3 ± (3 - 3)+0.0%
runtime.dotnet.mem.committed59.13 ± (59.02 - 59.23) MB59.19 ± (59.08 - 59.31) MB+0.1%✅⬆️
runtime.dotnet.threads.count29 ± (29 - 29)30 ± (29 - 30)+0.3%✅⬆️
.NET 6 - Baseline
process.internal_duration_ms208.39 ± (207.64 - 209.14) ms206.71 ± (206.06 - 207.36) ms-0.8%
process.time_to_main_ms76.38 ± (76.01 - 76.76) ms75.14 ± (74.89 - 75.38) ms-1.6%
runtime.dotnet.exceptions.count4 ± (4 - 4)4 ± (4 - 4)+0.0%
runtime.dotnet.mem.committed16.21 ± (16.19 - 16.23) MB16.24 ± (16.22 - 16.26) MB+0.2%✅⬆️
runtime.dotnet.threads.count19 ± (19 - 19)19 ± (19 - 19)+0.1%✅⬆️
.NET 6 - Bailout
process.internal_duration_ms213.47 ± (212.15 - 214.79) ms209.01 ± (208.19 - 209.83) ms-2.1%
process.time_to_main_ms78.50 ± (78.21 - 78.80) ms77.19 ± (76.85 - 77.52) ms-1.7%
runtime.dotnet.exceptions.count4 ± (4 - 4)4 ± (4 - 4)+0.0%
runtime.dotnet.mem.committed16.20 ± (16.18 - 16.22) MB16.24 ± (16.23 - 16.26) MB+0.3%✅⬆️
runtime.dotnet.threads.count20 ± (20 - 20)20 ± (20 - 20)-0.0%
.NET 6 - CallTarget+Inlining+NGEN
process.internal_duration_ms453.80 ± (449.94 - 457.66) ms450.33 ± (446.35 - 454.32) ms-0.8%
process.time_to_main_ms485.55 ± (484.65 - 486.45) ms487.70 ± (486.68 - 488.72) ms+0.4%✅⬆️
runtime.dotnet.exceptions.count4 ± (4 - 4)4 ± (4 - 4)+0.0%
runtime.dotnet.mem.committed58.90 ± (58.73 - 59.08) MB59.55 ± (59.39 - 59.70) MB+1.1%✅⬆️
runtime.dotnet.threads.count30 ± (29 - 30)30 ± (30 - 30)+0.3%✅⬆️
.NET 8 - Baseline
process.internal_duration_ms212.87 ± (211.88 - 213.85) ms209.86 ± (208.91 - 210.81) ms-1.4%
process.time_to_main_ms76.37 ± (76.09 - 76.66) ms75.31 ± (75.05 - 75.57) ms-1.4%
runtime.dotnet.exceptions.count4 ± (4 - 4)4 ± (4 - 4)+0.0%
runtime.dotnet.mem.committed11.50 ± (11.49 - 11.52) MB11.59 ± (11.57 - 11.60) MB+0.7%✅⬆️
runtime.dotnet.threads.count19 ± (19 - 19)19 ± (19 - 19)-0.3%
.NET 8 - Bailout
process.internal_duration_ms212.98 ± (211.70 - 214.26) ms211.60 ± (210.58 - 212.62) ms-0.6%
process.time_to_main_ms77.99 ± (77.59 - 78.40) ms77.37 ± (77.06 - 77.67) ms-0.8%
runtime.dotnet.exceptions.count4 ± (4 - 4)4 ± (4 - 4)+0.0%
runtime.dotnet.mem.committed11.54 ± (11.52 - 11.55) MB11.62 ± (11.60 - 11.64) MB+0.7%✅⬆️
runtime.dotnet.threads.count20 ± (20 - 20)20 ± (20 - 20)-0.1%
.NET 8 - CallTarget+Inlining+NGEN
process.internal_duration_ms457.43 ± (450.40 - 464.46) ms466.94 ± (459.45 - 474.43) ms+2.1%✅⬆️
process.time_to_main_ms473.51 ± (472.71 - 474.32) ms478.61 ± (476.91 - 480.31) ms+1.1%✅⬆️
runtime.dotnet.exceptions.count4 ± (4 - 4)4 ± (4 - 4)+0.0%
runtime.dotnet.mem.committed50.43 ± (50.34 - 50.52) MB50.31 ± (50.20 - 50.41) MB-0.2%
runtime.dotnet.threads.count29 ± (29 - 29)29 ± (29 - 29)-0.9%
Comparison explanation

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 highlighted in **red**. The following thresholds were used for comparing the execution times:

  • Welch test with statistical test for significance of 5%
  • Only results indicating a difference greater than 5% and 5 ms are considered.

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 charts
FakeDbCommand (.NET Framework 4.8)
gantt
    title Execution time (ms) FakeDbCommand (.NET Framework 4.8)
    dateFormat  x
    axisFormat %Q
    todayMarker off
    section Baseline
    This PR (8120) - mean (80ms)  : 77, 83
    master - mean (80ms)  : 77, 82

    section Bailout
    This PR (8120) - mean (84ms)  : 81, 88
    master - mean (84ms)  : 82, 86

    section CallTarget+Inlining+NGEN
    This PR (8120) - mean (1,123ms)  : 1067, 1179
    master - mean (1,116ms)  : 1068, 1163

Loading
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 (8120) - mean (127ms)  : 123, 130
    master - mean (127ms)  : 124, 130

    section Bailout
    This PR (8120) - mean (127ms)  : 123, 132
    master - mean (128ms)  : 125, 131

    section CallTarget+Inlining+NGEN
    This PR (8120) - mean (813ms)  : 759, 868
    master - mean (810ms)  : 758, 862

Loading
FakeDbCommand (.NET 6)
gantt
    title Execution time (ms) FakeDbCommand (.NET 6)
    dateFormat  x
    axisFormat %Q
    todayMarker off
    section Baseline
    This PR (8120) - mean (111ms)  : 108, 115
    master - mean (110ms)  : 105, 115

    section Bailout
    This PR (8120) - mean (113ms)  : 109, 116
    master - mean (111ms)  : 108, 114

    section CallTarget+Inlining+NGEN
    This PR (8120) - mean (781ms)  : 704, 857
    master - mean (770ms)  : 701, 838

Loading
FakeDbCommand (.NET 8)
gantt
    title Execution time (ms) FakeDbCommand (.NET 8)
    dateFormat  x
    axisFormat %Q
    todayMarker off
    section Baseline
    This PR (8120) - mean (109ms)  : 106, 113
    master - mean (108ms)  : 105, 112

    section Bailout
    This PR (8120) - mean (110ms)  : 107, 113
    master - mean (109ms)  : 106, 112

    section CallTarget+Inlining+NGEN
    This PR (8120) - mean (738ms)  : 712, 765
    master - mean (725ms)  : 700, 750

Loading
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 (8120) - mean (213ms)  : 199, 227
    master - mean (211ms)  : 201, 221

    section Bailout
    This PR (8120) - mean (218ms)  : 205, 231
    master - mean (223ms)  : 209, 236

    section CallTarget+Inlining+NGEN
    This PR (8120) - mean (1,241ms)  : 1122, 1361
    master - mean (1,224ms)  : 1139, 1308

Loading
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 (8120) - mean (307ms)  : 284, 330
    master - mean (301ms)  : 289, 314

    section Bailout
    This PR (8120) - mean (312ms)  : 287, 337
    master - mean (302ms)  : 287, 317

    section CallTarget+Inlining+NGEN
    This PR (8120) - mean (988ms)  : 931, 1045
    master - mean (984ms)  : 929, 1038

Loading
HttpMessageHandler (.NET 6)
gantt
    title Execution time (ms) HttpMessageHandler (.NET 6)
    dateFormat  x
    axisFormat %Q
    todayMarker off
    section Baseline
    This PR (8120) - mean (291ms)  : 277, 305
    master - mean (294ms)  : 280, 309

    section Bailout
    This PR (8120) - mean (295ms)  : 278, 313
    master - mean (302ms)  : 280, 324

    section CallTarget+Inlining+NGEN
    This PR (8120) - mean (975ms)  : 901, 1049
    master - mean (976ms)  : 917, 1034

Loading
HttpMessageHandler (.NET 8)
gantt
    title Execution time (ms) HttpMessageHandler (.NET 8)
    dateFormat  x
    axisFormat %Q
    todayMarker off
    section Baseline
    This PR (8120) - mean (296ms)  : 280, 312
    master - mean (300ms)  : 281, 319

    section Bailout
    This PR (8120) - mean (300ms)  : 282, 318
    master - mean (302ms)  : 276, 328

    section CallTarget+Inlining+NGEN
    This PR (8120) - mean (971ms)  : 834, 1109
    master - mean (965ms)  : 858, 1072

Loading

@bouwkast bouwkast marked this pull request as ready for review February 2, 2026 13:47
@bouwkast bouwkast requested a review from a team as a code owner February 2, 2026 13:47
Copy link
Member

@andrewlock andrewlock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks

return false;
}

// Check prefix character by character to avoid allocation (lowercase only)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You know, I'm wondering if we should be using StartsWith() and similar here and in other places in this method, to take advantage of SIMD in newer runtimes 🤔 I might have a little play with benchmarking to see what the result is

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use StartsWith() regardless. What allocation are we trying to avoid here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, I explored this, but the results weren't that impressive...

For high number of iterations, where tiered jit kicks in, SIMD can be a lot faster (2ns vs 14ns) for the "worst" case scenario (where a match is found)

Method Categories Mean Ratio
TempPathTrue_BestCase_Simd BestCase 2.543 ns 1.33
TempPathTrue_BestCase_Original BestCase 1.911 ns 1.00
TempPathTrue_WorstCase_Simd WorstCase 2.557 ns 0.18
TempPathTrue_WorstCase_Original WorstCase 14.230 ns 1.00

However, making some minor modifications (remove branches, aggressively inline) to the current code makes the discrepancy much less:

Method Categories Mean Ratio
TempPathTrue_BestCase_Simd BestCase 2.5783 ns 2.61
TempPathTrue_BestCase_Updated BestCase 0.9896 ns 1.00
TempPathTrue_WorstCase_Simd WorstCase 2.5189 ns 0.78
TempPathTrue_WorstCase_Updated WorstCase 3.2491 ns 1.00

and if we force the benchmarks to be low repetition and to not hit Tier 1 jitting, simd looks much worse overall:

Method Categories Mean Ratio
TempPathTrue_BestCase_Simd BestCase 28.898 ns 4.15
TempPathTrue_BestCase_Updated BestCase 6.992 ns 1.00
TempPathTrue_WorstCase_Simd WorstCase 32.573 ns 1.03
TempPathTrue_WorstCase_Updated WorstCase 31.874 ns 1.01

Given that this is prob only called 100-1000 times(?ish, i.e. once per assembly), we need to think about the "early" cases almost as much as the "later" cases. So I think not using SIMD is the better option, and minor tweaks to existing code is prob"good enough".

I'll look at making those tweaks in subsequent PRs

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, thanks!

Co-authored-by: Andrew Lock <andrew.lock@datadoghq.com>
@bouwkast bouwkast enabled auto-merge (squash) February 5, 2026 14:46
@bouwkast bouwkast merged commit 5d8d01b into master Feb 5, 2026
141 of 142 checks passed
@bouwkast bouwkast deleted the steven/filter-more-assemblies branch February 5, 2026 15:32
@github-actions github-actions bot added this to the vNext-v3 milestone Feb 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI Generated Largely based on code generated by an AI or LLM. This label is the same across all dd-trace-* repos

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants