Skip to content

Filter the benchmark job, drop netframework4.8, pin nuget sources - #377

Merged
twcclegg merged 4 commits into
mainfrom
ci/perf-filter-and-supply-chain
Aug 5, 2026
Merged

Filter the benchmark job, drop netframework4.8, pin nuget sources#377
twcclegg merged 4 commits into
mainfrom
ci/perf-filter-and-supply-chain

Conversation

@twcclegg

@twcclegg twcclegg commented Aug 5, 2026

Copy link
Copy Markdown
Owner

Four items. Three landed; the fourth was measured and rejected.

The benchmark job only runs when it could have moved

A paths: filter on run_performance_tests, which at ~12 minutes is the longest job in the repo and
previously ran on every PR including documentation-only ones. csharp/PhoneNumbers/** is in the list
deliberately: PerformanceTest is not in the solution, so nothing else compiles it and a library
change could otherwise break the benchmarks unnoticed.

Checked branch protection first — no required status checks, strict: false — so a skipped run
cannot block a merge and the usual always-pass-on-skip workaround is unnecessary. The list is
duplicated across the pull_request and push triggers because GitHub Actions does not support YAML
anchors; the anchored version parses locally and fails there.

netframework4.8 is gone from the test projects

It only ever built on Windows, and there are no Windows runners, so it was exercised only if a
contributor happened to run tests locally. Its System.Text.RegularExpressions reference and
PackageVersion entry go with it.

This unblocks something: the OS-conditional TFM list was exactly why those two projects were excluded
from lock files in #373 — a lock file generated on Linux omitted a framework a Windows contributor
would restore. With the list now unconditional, both have committed packages.lock.json files and
are covered by --locked-mode.

nuget.config

<clear /> discards any source a machine- or user-level config would otherwise contribute, so a
restore resolves from nuget.org and nowhere else. Package source mapping changes nothing with a
single source; it matters the moment a second one is added, since without it any source can serve any
package id.

Benchmark job speed

Two trees now build concurrently before benchmarking (~6%), and the redundant PhoneNumberCount=10000
case is dropped (~7%) — the 1000 and 10000 results have agreed in direction and magnitude in every
same-runner comparison, so it demonstrated linear scaling rather than testing anything.

The benchmarks themselves still run strictly one after another. Running them concurrently would have
base and branch competing for the same cores, which would undo the same-runner comparison that caught
a real 2% regression in #374.

Reducing iteration counts was tried and reverted. Measuring first showed where the time actually
goes: 12 cases at ~22–27s each regardless of how fast the operation is (BDN's fixed per-case cost),
plus ~37% in per-class project generation. warmupCount: 3, iterationCount: 7 cut ~20% but cost far
more precision than predicted — base and branch ran in the same job, so this is a controlled
comparison:

benchmark 15 iterations 7 iterations
GetDisplayCountry 0.18% 7.95%
InputDigitPerKeystroke 0.26% 2.34%
FindNumbers_StrictGrouping 0.15% 1.26%

At 2.34% relative error, InputDigitPerKeystroke could no longer resolve the 2% regression this
harness caught two PRs ago. Extra iterations were averaging out run-to-run instability, not just
sampling noise — which is why the degradation was 8–44× rather than the √(15/7)≈1.5× a
sampling-only model predicts. Reverted, and the error bars are confirmed back under 0.6%.

Recorded here so it isn't re-attempted without knowing the cost.

@codecov

codecov Bot commented Aug 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.01%. Comparing base (8369463) to head (ca194fd).
⚠️ Report is 5 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #377   +/-   ##
=======================================
  Coverage   98.01%   98.01%           
=======================================
  Files          39       39           
  Lines       52818    52818           
  Branches     1105     1105           
=======================================
  Hits        51770    51770           
  Misses        795      795           
  Partials      253      253           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

📊 Benchmark Results

Commit: ca194fd · Full run · Linux ubuntu-24.04-arm

Both sides were measured on the same runner in the same job, so the numbers are
comparable. Treat sub-percent differences as noise.

PR branch

BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
Neoverse-N2, 4 physical cores
.NET SDK 10.0.302
  [Host]    : .NET 10.0.10 (10.0.10, 10.0.1026.32716), Arm64 RyuJIT armv8.0-a
  .NET 10.0 : .NET 10.0.10 (10.0.10, 10.0.1026.32716), Arm64 RyuJIT armv8.0-a

Job=.NET 10.0  Runtime=.NET 10.0  

Method PhoneNumberCount Mean Error StdDev Gen0 Allocated
InputDigitPerKeystroke 1000 4.317 ms 0.0237 ms 0.0221 ms 54.6875 3.87 MB

BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
Neoverse-N2, 4 physical cores
.NET SDK 10.0.302
  [Host]     : .NET 10.0.10 (10.0.10, 10.0.1026.32716), Arm64 RyuJIT armv8.0-a
  Job-AMQORM : .NET 10.0.10 (10.0.10, 10.0.1026.32716), Arm64 RyuJIT armv8.0-a

Runtime=.NET 10.0  InvocationCount=1  IterationCount=20  
LaunchCount=1  RunStrategy=ColdStart  UnrollFactor=1  
WarmupCount=1  

Method Mean Error StdDev Allocated
CreateInstance 393.8 μs 93.88 μs 108.1 μs 119.48 KB
CreateInstanceAndLoadAllRegions 7,014.4 μs 369.11 μs 425.1 μs 1619.1 KB
FirstRegionLookup 434.7 μs 127.15 μs 146.4 μs 124.54 KB

BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
Neoverse-N2, 4 physical cores
.NET SDK 10.0.302
  [Host]    : .NET 10.0.10 (10.0.10, 10.0.1026.32716), Arm64 RyuJIT armv8.0-a
  .NET 10.0 : .NET 10.0.10 (10.0.10, 10.0.1026.32716), Arm64 RyuJIT armv8.0-a

Job=.NET 10.0  Runtime=.NET 10.0  

Method PhoneNumberCount Mean Error StdDev Gen0 Allocated
ExtractPossibleNumber_CleanInput 1000 21.83 μs 0.027 μs 0.025 μs - -
ExtractPossibleNumber_WithLeadingJunk 1000 37.99 μs 0.053 μs 0.050 μs 0.6714 48360 B

BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
Neoverse-N2, 4 physical cores
.NET SDK 10.0.302
  [Host]    : .NET 10.0.10 (10.0.10, 10.0.1026.32716), Arm64 RyuJIT armv8.0-a
  .NET 10.0 : .NET 10.0.10 (10.0.10, 10.0.1026.32716), Arm64 RyuJIT armv8.0-a

Job=.NET 10.0  Runtime=.NET 10.0  

Method PhoneNumberCount Mean Error StdDev Gen0 Allocated
FindNumbers_Valid 100 140.2 μs 0.40 μs 0.38 μs 0.9766 69.93 KB
FindNumbers_StrictGrouping 100 317.4 μs 0.75 μs 0.66 μs 1.4648 123.2 KB

BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
Neoverse-N2, 4 physical cores
.NET SDK 10.0.302
  [Host]    : .NET 10.0.10 (10.0.10, 10.0.1026.32716), Arm64 RyuJIT armv8.0-a
  .NET 10.0 : .NET 10.0.10 (10.0.10, 10.0.1026.32716), Arm64 RyuJIT armv8.0-a

Job=.NET 10.0  Runtime=.NET 10.0  

Method PhoneNumberCount Mean Error StdDev Gen0 Allocated
GetDescriptionForNumber 1000 1,406.70 μs 3.322 μs 3.107 μs 1.9531 196.63 KB
GetDisplayCountry 1000 23.17 μs 0.036 μs 0.034 μs 0.0916 7.56 KB

BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
Neoverse-N2, 4 physical cores
.NET SDK 10.0.302
  [Host]    : .NET 10.0.10 (10.0.10, 10.0.1026.32716), Arm64 RyuJIT armv8.0-a
  .NET 10.0 : .NET 10.0.10 (10.0.10, 10.0.1026.32716), Arm64 RyuJIT armv8.0-a

Job=.NET 10.0  Runtime=.NET 10.0  

Method PhoneNumberCount Mean Error StdDev Gen0 Allocated
ParseValidateAndFormatPhoneNumbers 1000 2.415 ms 0.0041 ms 0.0039 ms 7.8125 580.51 KB
PR base

BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
Neoverse-N2, 4 physical cores
.NET SDK 10.0.302
  [Host]    : .NET 10.0.10 (10.0.10, 10.0.1026.32716), Arm64 RyuJIT armv8.0-a
  .NET 10.0 : .NET 10.0.10 (10.0.10, 10.0.1026.32716), Arm64 RyuJIT armv8.0-a

Job=.NET 10.0  Runtime=.NET 10.0  

Method PhoneNumberCount Mean Error StdDev Gen0 Allocated
InputDigitPerKeystroke 1000 4.290 ms 0.0104 ms 0.0097 ms 54.6875 3.87 MB

BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
Neoverse-N2, 4 physical cores
.NET SDK 10.0.302
  [Host]     : .NET 10.0.10 (10.0.10, 10.0.1026.32716), Arm64 RyuJIT armv8.0-a
  Job-AMQORM : .NET 10.0.10 (10.0.10, 10.0.1026.32716), Arm64 RyuJIT armv8.0-a

Runtime=.NET 10.0  InvocationCount=1  IterationCount=20  
LaunchCount=1  RunStrategy=ColdStart  UnrollFactor=1  
WarmupCount=1  

Method Mean Error StdDev Allocated
CreateInstance 391.4 μs 107.1 μs 123.3 μs 119.48 KB
CreateInstanceAndLoadAllRegions 6,987.3 μs 354.4 μs 408.1 μs 1619.1 KB
FirstRegionLookup 460.7 μs 152.6 μs 175.7 μs 124.54 KB

BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
Neoverse-N2, 4 physical cores
.NET SDK 10.0.302
  [Host]    : .NET 10.0.10 (10.0.10, 10.0.1026.32716), Arm64 RyuJIT armv8.0-a
  .NET 10.0 : .NET 10.0.10 (10.0.10, 10.0.1026.32716), Arm64 RyuJIT armv8.0-a

Job=.NET 10.0  Runtime=.NET 10.0  

Method PhoneNumberCount Mean Error StdDev Gen0 Allocated
ExtractPossibleNumber_CleanInput 1000 20.90 μs 0.014 μs 0.012 μs - -
ExtractPossibleNumber_WithLeadingJunk 1000 38.46 μs 0.044 μs 0.039 μs 0.6714 48360 B

BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
Neoverse-N2, 4 physical cores
.NET SDK 10.0.302
  [Host]    : .NET 10.0.10 (10.0.10, 10.0.1026.32716), Arm64 RyuJIT armv8.0-a
  .NET 10.0 : .NET 10.0.10 (10.0.10, 10.0.1026.32716), Arm64 RyuJIT armv8.0-a

Job=.NET 10.0  Runtime=.NET 10.0  

Method PhoneNumberCount Mean Error StdDev Gen0 Allocated
FindNumbers_Valid 100 138.9 μs 0.26 μs 0.22 μs 0.9766 69.93 KB
FindNumbers_StrictGrouping 100 313.5 μs 0.69 μs 0.65 μs 1.4648 123.2 KB

BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
Neoverse-N2, 4 physical cores
.NET SDK 10.0.302
  [Host]    : .NET 10.0.10 (10.0.10, 10.0.1026.32716), Arm64 RyuJIT armv8.0-a
  .NET 10.0 : .NET 10.0.10 (10.0.10, 10.0.1026.32716), Arm64 RyuJIT armv8.0-a

Job=.NET 10.0  Runtime=.NET 10.0  

Method PhoneNumberCount Mean Error StdDev Gen0 Allocated
GetDescriptionForNumber 1000 1,377.35 μs 2.858 μs 2.673 μs 1.9531 196.63 KB
GetDisplayCountry 1000 23.40 μs 0.038 μs 0.035 μs 0.0916 7.56 KB

BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat)
Neoverse-N2, 4 physical cores
.NET SDK 10.0.302
  [Host]    : .NET 10.0.10 (10.0.10, 10.0.1026.32716), Arm64 RyuJIT armv8.0-a
  .NET 10.0 : .NET 10.0.10 (10.0.10, 10.0.1026.32716), Arm64 RyuJIT armv8.0-a

Job=.NET 10.0  Runtime=.NET 10.0  

Method PhoneNumberCount Mean Error StdDev Gen0 Allocated
ParseValidateAndFormatPhoneNumbers 1000 2.424 ms 0.0048 ms 0.0043 ms 7.8125 580.51 KB
ParseValidateAndFormatPhoneNumbers 10000 24.848 ms 0.0620 ms 0.0580 ms 62.5000 5798.53 KB

@twcclegg
twcclegg marked this pull request as ready for review August 5, 2026 21:50
@twcclegg
twcclegg merged commit ab514e1 into main Aug 5, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant