Skip to content

Commit 19527a5

Browse files
ci: update benchmark workflow for net11 (#1731)
1 parent 944e589 commit 19527a5

5 files changed

Lines changed: 67 additions & 62 deletions

File tree

.github/workflows/benchmarks-baseline-vs-current.yml

Lines changed: 51 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ on:
77
description: 'NuGet version of Humanizer to use for the baseline run'
88
required: true
99
type: string
10-
default: '3.0.0-rc.6'
10+
default: '3.0.10'
1111

1212
push:
1313
paths:
@@ -21,58 +21,65 @@ on:
2121

2222
jobs:
2323
benchmark:
24-
name: Run Benchmarks (${{ matrix.kind }})
24+
name: Run Benchmarks (${{ matrix.kind }}, ${{ matrix.targetFramework }})
2525
runs-on: ubuntu-latest
2626
timeout-minutes: 180
2727
env:
28-
BASELINE_VERSION: ${{ inputs.baselineVersion || '3.0.0-rc.6' }}
28+
BASELINE_VERSION: ${{ inputs.baselineVersion || '3.0.10' }}
2929
strategy:
30+
fail-fast: false
3031
matrix:
3132
kind: [baseline, current]
33+
targetFramework: [net10.0, net11.0]
3234

3335
steps:
3436
- name: Checkout repository
3537
uses: actions/checkout@v5
3638
with:
3739
fetch-depth: 0
3840

39-
- name: Setup .NET 8,10
41+
- name: Setup .NET 10
4042
uses: actions/setup-dotnet@v5
4143
with:
42-
dotnet-version: |
43-
8.0
44-
10.0
45-
44+
dotnet-version: '10.0.x'
45+
46+
- name: Setup .NET 11 preview
47+
uses: actions/setup-dotnet@v5
48+
with:
49+
dotnet-version: '11.0.x'
50+
dotnet-quality: preview
51+
4652
- name: Display run information
4753
run: |
4854
echo "## Benchmark Run: ${{ matrix.kind }}" >> $GITHUB_STEP_SUMMARY
4955
echo "" >> $GITHUB_STEP_SUMMARY
5056
echo "- **Commit SHA:** ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
5157
echo "- **Baseline Version:** ${{ env.BASELINE_VERSION }}" >> $GITHUB_STEP_SUMMARY
5258
echo "- **Run Type:** ${{ matrix.kind }}" >> $GITHUB_STEP_SUMMARY
59+
echo "- **Target Framework:** ${{ matrix.targetFramework }}" >> $GITHUB_STEP_SUMMARY
5360
echo "" >> $GITHUB_STEP_SUMMARY
5461
5562
- name: Build Benchmarks (baseline)
5663
if: matrix.kind == 'baseline'
5764
run: |
58-
out="artifacts/baseline"
65+
out="artifacts/baseline/${{ matrix.targetFramework }}"
5966
mkdir -p "$out"
60-
dotnet run --project src/Benchmarks/Benchmarks.csproj -c Release -f net8.0 -- --filter '*' --artifacts "$out" --envVars UseBaselinePackage:true,BaselinePackageVersion:${{ env.BASELINE_VERSION }}
67+
dotnet run --project src/Benchmarks/Benchmarks.csproj -c Release -f ${{ matrix.targetFramework }} -p:UseBaselinePackage=true -p:BaselinePackageVersion=${{ env.BASELINE_VERSION }} -- --filter '*' --artifacts "$out"
6168
6269
- name: Build Benchmarks (current)
6370
if: matrix.kind == 'current'
6471
run: |
65-
out="artifacts/current"
72+
out="artifacts/current/${{ matrix.targetFramework }}"
6673
mkdir -p "$out"
67-
dotnet run --project src/Benchmarks/Benchmarks.csproj -c Release -f net8.0 -- --filter '*' --artifacts "$out"
74+
dotnet run --project src/Benchmarks/Benchmarks.csproj -c Release -f ${{ matrix.targetFramework }} -- --filter '*' --artifacts "$out"
6875
6976
- name: Append Results to Summary
7077
run: |
71-
out="artifacts/${{ matrix.kind }}"
78+
out="artifacts/${{ matrix.kind }}/${{ matrix.targetFramework }}"
7279
7380
# Find all markdown files and append them to the summary
7481
echo "" >> $GITHUB_STEP_SUMMARY
75-
echo "### Benchmark Results (${{ matrix.kind }})" >> $GITHUB_STEP_SUMMARY
82+
echo "### Benchmark Results (${{ matrix.kind }}, ${{ matrix.targetFramework }})" >> $GITHUB_STEP_SUMMARY
7683
echo "" >> $GITHUB_STEP_SUMMARY
7784
7885
while IFS= read -r MD; do
@@ -83,23 +90,27 @@ jobs:
8390
- name: Upload JSON Artifacts
8491
uses: actions/upload-artifact@v4
8592
with:
86-
name: humanizer-bdn-${{ matrix.kind }}-json
87-
path: artifacts/${{ matrix.kind }}/**/*.json
93+
name: humanizer-bdn-${{ matrix.kind }}-${{ matrix.targetFramework }}-json
94+
path: artifacts/${{ matrix.kind }}/${{ matrix.targetFramework }}/**/*.json
8895
retention-days: 7
8996

9097
- name: Upload All Artifacts
9198
uses: actions/upload-artifact@v4
9299
with:
93-
name: humanizer-bdn-${{ matrix.kind }}-all
94-
path: artifacts/${{ matrix.kind }}/
100+
name: humanizer-bdn-${{ matrix.kind }}-${{ matrix.targetFramework }}-all
101+
path: artifacts/${{ matrix.kind }}/${{ matrix.targetFramework }}/
95102
retention-days: 7
96103

97104
compare:
98-
name: Compare Baseline vs Current
105+
name: Compare Baseline vs Current (${{ matrix.targetFramework }})
99106
runs-on: ubuntu-latest
100107
needs: benchmark
101108
env:
102-
BASELINE_VERSION: ${{ inputs.baselineVersion || '3.0.0-rc.6' }}
109+
BASELINE_VERSION: ${{ inputs.baselineVersion || '3.0.10' }}
110+
strategy:
111+
fail-fast: false
112+
matrix:
113+
targetFramework: [net10.0, net11.0]
103114

104115
steps:
105116
- name: Checkout repository
@@ -110,25 +121,32 @@ jobs:
110121
- name: Download Baseline JSON
111122
uses: actions/download-artifact@v4
112123
with:
113-
name: humanizer-bdn-baseline-json
124+
name: humanizer-bdn-baseline-${{ matrix.targetFramework }}-json
114125
path: baseline
115126

116127
- name: Download Current JSON
117128
uses: actions/download-artifact@v4
118129
with:
119-
name: humanizer-bdn-current-json
130+
name: humanizer-bdn-current-${{ matrix.targetFramework }}-json
120131
path: current
121132

122-
- name: Setup .NET
133+
- name: Setup .NET 10
134+
uses: actions/setup-dotnet@v5
135+
with:
136+
dotnet-version: '10.0.x'
137+
138+
- name: Setup .NET 11 preview
123139
uses: actions/setup-dotnet@v5
124140
with:
125-
dotnet-version: '10.x'
141+
dotnet-version: '11.0.x'
142+
dotnet-quality: preview
126143

127144
- name: Clone and Build ResultsComparer
128145
run: |
129146
git clone --depth 1 https://github.com/dotnet/performance
130147
131-
- name: Split Benchmark Results by TFM
148+
- name: Locate Benchmark Results
149+
id: results
132150
run: |
133151
set -euo pipefail
134152
@@ -147,34 +165,24 @@ jobs:
147165
148166
echo "Using baseline results directory: $baseline_results"
149167
echo "Using current results directory: $current_results"
150-
151-
pwsh -File src/scripts/split-benchmark-results.ps1 -InputDir "$baseline_results" -OutputRoot baseline-split
152-
pwsh -File src/scripts/split-benchmark-results.ps1 -InputDir "$current_results" -OutputRoot current-split
168+
echo "baseline_results=$baseline_results" >> "$GITHUB_OUTPUT"
169+
echo "current_results=$current_results" >> "$GITHUB_OUTPUT"
153170
154171
- name: Run ResultsComparer for each TFM
155172
run: |
156173
mkdir -p comparisons
157-
158-
# Compare each target framework independently
159-
for tfm_dir in baseline-split/*; do
160-
if [ -d "$tfm_dir" ]; then
161-
tfm=$(basename "$tfm_dir")
162-
echo "Comparing results for $tfm..."
163-
164-
if [ -d "current-split/$tfm" ]; then
165-
dotnet run --project performance/src/tools/ResultsComparer/ResultsComparer.csproj -c Release -p:PERFLAB_TARGET_FRAMEWORKS=net10.0 -f net10.0 --base "$tfm_dir" --diff "current-split/$tfm" --threshold "5%" > "comparisons/diff-$tfm.md" || true
166-
else
167-
echo "⚠️ No current results found for $tfm" > "comparisons/diff-$tfm.md"
168-
fi
169-
fi
170-
done
174+
tfm="${{ matrix.targetFramework }}"
175+
176+
echo "Comparing results for $tfm..."
177+
dotnet run --project performance/src/tools/ResultsComparer/ResultsComparer.csproj -c Release -p:PERFLAB_TARGET_FRAMEWORKS=net10.0 -f net10.0 --base "${{ steps.results.outputs.baseline_results }}" --diff "${{ steps.results.outputs.current_results }}" --threshold "5%" > "comparisons/diff-$tfm.md" || true
171178
172179
- name: Append Comparison to Summary
173180
run: |
174181
echo "" >> $GITHUB_STEP_SUMMARY
175182
echo "## Performance Comparison: Baseline vs Current" >> $GITHUB_STEP_SUMMARY
176183
echo "" >> $GITHUB_STEP_SUMMARY
177184
echo "**Baseline Version:** ${{ env.BASELINE_VERSION }}" >> $GITHUB_STEP_SUMMARY
185+
echo "**Target Framework:** ${{ matrix.targetFramework }}" >> $GITHUB_STEP_SUMMARY
178186
echo "" >> $GITHUB_STEP_SUMMARY
179187
180188
# Append comparison for each TFM
@@ -196,6 +204,6 @@ jobs:
196204
uses: actions/upload-artifact@v4
197205
if: always()
198206
with:
199-
name: humanizer-bdn-comparison
207+
name: humanizer-bdn-comparison-${{ matrix.targetFramework }}
200208
path: comparisons/
201209
retention-days: 7

src/Benchmarks/Benchmarks.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFrameworks>net11.0;net10.0;net8.0</TargetFrameworks>
5+
<TargetFrameworks>net11.0;net10.0</TargetFrameworks>
66
<UseBaselinePackage Condition="'$(UseBaselinePackage)' == ''">false</UseBaselinePackage>
77
<BaselinePackageVersion Condition="'$(BaselinePackageVersion)' == ''">3.0.10</BaselinePackageVersion>
88
<ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
99
</PropertyGroup>
1010

1111
<ItemGroup>
12-
<PackageReference Include="BenchmarkDotNet" Version ="0.15.8" />
12+
<PackageReference Include="BenchmarkDotNet" Version="0.15.8" />
1313
</ItemGroup>
1414

1515
<!-- Use baseline package from NuGet for comparison -->
1616
<ItemGroup Condition="'$(UseBaselinePackage)' == 'true'">
17-
<PackageReference Include="Humanizer" Version="$(BaselinePackageVersion)" />
17+
<PackageReference Include="Humanizer" Version="$(BaselinePackageVersion)" />
1818
</ItemGroup>
1919

2020
<!-- Use current source code from the repo -->

src/Benchmarks/Program.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
using BenchmarkDotNet.Configs;
22
using BenchmarkDotNet.Diagnosers;
3-
using BenchmarkDotNet.Environments;
43
using BenchmarkDotNet.Exporters;
54
using BenchmarkDotNet.Exporters.Json;
65
using BenchmarkDotNet.Jobs;
6+
using BenchmarkDotNet.Toolchains.InProcess.Emit;
77

88
var config = ManualConfig.Create(DefaultConfig.Instance)
99
.AddJob(Job.Default
10-
.WithRuntime(CoreRuntime.Core10_0))
11-
.AddJob(Job.Default
12-
.AsBaseline()
13-
.WithRuntime(CoreRuntime.Core80))
10+
.WithToolchain(InProcessEmitToolchain.Instance))
1411
.AddExporter(JsonExporter.Full)
1512
.AddExporter(MarkdownExporter.GitHub)
1613
.AddDiagnoser(MemoryDiagnoser.Default);

src/Benchmarks/README.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,25 @@ A manual GitHub Actions workflow is available to compare performance between a b
2323

2424
1. Go to **Actions****Benchmark Baseline vs Current**
2525
2. Click **Run workflow**
26-
3. Enter the baseline version (default: 2.14.1)
26+
3. Enter the baseline version (default: 3.0.10)
2727
4. The workflow will:
28-
- Run benchmarks against the baseline package in parallel
29-
- Run benchmarks against the current source code in parallel
28+
- Run benchmarks against the baseline package for .NET 10 and .NET 11 in parallel
29+
- Run benchmarks against the current source code for .NET 10 and .NET 11 in parallel
3030
- Compare results using ResultsComparer
3131
- Publish detailed reports as artifacts
3232
- Display results and comparison in the job summary
3333

3434
**How it works:**
3535
- **Baseline run**: Builds benchmarks with `UseBaselinePackage=true` to reference the NuGet package
3636
- **Current run**: Builds benchmarks with `UseBaselinePackage=false` to reference the local source code
37-
- **Comparison**: Downloads both JSON results and uses `dotnet/performance` ResultsComparer tool to generate a diff table
37+
- **Comparison**: Downloads the .NET 10 and .NET 11 JSON results and uses `dotnet/performance` ResultsComparer tool to generate diff tables
3838

3939
**Artifacts available after each run:**
40-
- `humanizer-bdn-baseline-json` - Full JSON results from baseline
41-
- `humanizer-bdn-current-json` - Full JSON results from current code
42-
- `humanizer-bdn-baseline-all` - Complete BenchmarkDotNet artifacts (baseline)
43-
- `humanizer-bdn-current-all` - Complete BenchmarkDotNet artifacts (current)
44-
- `humanizer-bdn-comparison` - ResultsComparer diff report
40+
- `humanizer-bdn-baseline-<tfm>-json` - Full JSON results from baseline
41+
- `humanizer-bdn-current-<tfm>-json` - Full JSON results from current code
42+
- `humanizer-bdn-baseline-<tfm>-all` - Complete BenchmarkDotNet artifacts (baseline)
43+
- `humanizer-bdn-current-<tfm>-all` - Complete BenchmarkDotNet artifacts (current)
44+
- `humanizer-bdn-comparison-<tfm>` - ResultsComparer diff report
4545

4646
## Benchmark Suites
4747

@@ -175,7 +175,7 @@ All benchmarks include `[MemoryDiagnoser]` to track allocations. The optimizatio
175175

176176
## Notes
177177

178-
- Benchmarks run on .NET 10.0 to demonstrate maximum performance
178+
- Benchmarks run on .NET 10.0 and .NET 11.0 to demonstrate performance on supported modern frameworks
179179
- Performance improvements are most significant on modern frameworks
180180
- Older frameworks (.NET 4.8, netstandard2.0) still benefit from FrozenDictionary via polyfills
181181
- Results may vary based on hardware and workload characteristics

src/scripts/split-benchmark-results.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ param(
77
# Keys are substrings or regexes you expect in the runtime name.
88
# Left to right match wins. Add or reorder as needed.
99
$TfmMap = @(
10+
@{ Pattern = '^\.NET\s+11(\.0)?$'; Tfm = 'net11.0' }
1011
@{ Pattern = '^\.NET\s+10(\.0)?$'; Tfm = 'net10.0' }
11-
@{ Pattern = '^\.NET\s+8(\.0)?$'; Tfm = 'net8.0' }
1212
@{ Pattern = '^\.NET\s+Framework\s*4\.8$'; Tfm = 'net48' }
1313
)
1414
$DefaultTfm = 'unknown'

0 commit comments

Comments
 (0)