diff --git a/.gitignore b/.gitignore
index a516f25e83a..dbc94ceb5ea 100644
--- a/.gitignore
+++ b/.gitignore
@@ -118,7 +118,9 @@ UpgradeLog*.XML
artifacts
build
-BenchmarkDotNet.Artifacts
+
+**/BenchmarkDotNet.Artifacts/**/*.*
+
tools
*.lock.json
@@ -129,3 +131,5 @@ coverage.*.json
coverage-reports/
!eng/**
+
+!**/BenchmarkDotNet.Artifacts/**/*.md
diff --git a/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.CircuitBreakerBenchmark-report-github.md b/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.CircuitBreakerBenchmark-report-github.md
new file mode 100644
index 00000000000..967715e172d
--- /dev/null
+++ b/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.CircuitBreakerBenchmark-report-github.md
@@ -0,0 +1,15 @@
+``` ini
+
+BenchmarkDotNet=v0.13.5, OS=Windows 11 (10.0.22621.1702/22H2/2022Update/SunValley2), VM=Hyper-V
+Intel Xeon Platinum 8370C CPU 2.80GHz, 1 CPU, 16 logical and 8 physical cores
+.NET SDK=7.0.302
+ [Host] : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2
+
+Job=MediumRun Toolchain=InProcessEmitToolchain IterationCount=15
+LaunchCount=2 WarmupCount=10
+
+```
+| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
+|------------------------- |---------:|--------:|--------:|------:|--------:|-------:|----------:|------------:|
+| ExecuteCircuitBreaker_V7 | 314.0 ns | 3.45 ns | 4.94 ns | 1.00 | 0.00 | 0.0200 | 504 B | 1.00 |
+| ExecuteCircuitBreaker_V8 | 468.3 ns | 1.83 ns | 2.51 ns | 1.49 | 0.03 | 0.0010 | 32 B | 0.06 |
diff --git a/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.GenericOverheadBenchmark-report-github.md b/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.GenericOverheadBenchmark-report-github.md
new file mode 100644
index 00000000000..9ec9e12512a
--- /dev/null
+++ b/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.GenericOverheadBenchmark-report-github.md
@@ -0,0 +1,15 @@
+``` ini
+
+BenchmarkDotNet=v0.13.5, OS=Windows 11 (10.0.22621.1702/22H2/2022Update/SunValley2), VM=Hyper-V
+Intel Xeon Platinum 8370C CPU 2.80GHz, 1 CPU, 16 logical and 8 physical cores
+.NET SDK=7.0.302
+ [Host] : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2
+
+Job=MediumRun Toolchain=InProcessEmitToolchain IterationCount=15
+LaunchCount=2 WarmupCount=10
+
+```
+| Method | Mean | Error | StdDev | Ratio | RatioSD | Allocated | Alloc Ratio |
+|------------------------ |---------:|---------:|---------:|------:|--------:|----------:|------------:|
+| ExecuteAsync_Generic | 29.58 ns | 0.103 ns | 0.155 ns | 1.00 | 0.00 | - | NA |
+| ExecuteAsync_NonGeneric | 32.72 ns | 0.334 ns | 0.490 ns | 1.11 | 0.02 | - | NA |
diff --git a/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.HedgingBenchmark-report-github.md b/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.HedgingBenchmark-report-github.md
new file mode 100644
index 00000000000..c99b05a154e
--- /dev/null
+++ b/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.HedgingBenchmark-report-github.md
@@ -0,0 +1,17 @@
+``` ini
+
+BenchmarkDotNet=v0.13.5, OS=Windows 11 (10.0.22621.1702/22H2/2022Update/SunValley2), VM=Hyper-V
+Intel Xeon Platinum 8370C CPU 2.80GHz, 1 CPU, 16 logical and 8 physical cores
+.NET SDK=7.0.302
+ [Host] : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2
+
+Job=MediumRun Toolchain=InProcessEmitToolchain IterationCount=15
+LaunchCount=2 WarmupCount=10
+
+```
+| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Allocated | Alloc Ratio |
+|---------------------------- |-----------:|----------:|----------:|------:|--------:|-------:|-------:|----------:|------------:|
+| Hedging_Primary | 958.3 ns | 4.36 ns | 6.52 ns | 1.00 | 0.00 | 0.0019 | - | 80 B | 1.00 |
+| Hedging_Secondary | 1,817.0 ns | 11.59 ns | 17.35 ns | 1.90 | 0.01 | 0.0095 | - | 280 B | 3.50 |
+| Hedging_Primary_AsyncWork | 5,000.9 ns | 164.21 ns | 235.50 ns | 5.21 | 0.23 | 0.0458 | 0.0229 | 1244 B | 15.55 |
+| Hedging_Secondary_AsyncWork | 7,898.5 ns | 181.13 ns | 271.10 ns | 8.24 | 0.26 | 0.0687 | 0.0610 | 1755 B | 21.94 |
diff --git a/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.MultipleStrategiesBenchmark-report-github.md b/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.MultipleStrategiesBenchmark-report-github.md
new file mode 100644
index 00000000000..660efba193c
--- /dev/null
+++ b/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.MultipleStrategiesBenchmark-report-github.md
@@ -0,0 +1,15 @@
+``` ini
+
+BenchmarkDotNet=v0.13.5, OS=Windows 11 (10.0.22621.1702/22H2/2022Update/SunValley2), VM=Hyper-V
+Intel Xeon Platinum 8370C CPU 2.80GHz, 1 CPU, 16 logical and 8 physical cores
+.NET SDK=7.0.302
+ [Host] : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2
+
+Job=MediumRun Toolchain=InProcessEmitToolchain IterationCount=15
+LaunchCount=2 WarmupCount=10
+
+```
+| Method | Mean | Error | StdDev | Ratio | Gen0 | Allocated | Alloc Ratio |
+|--------------------------- |---------:|----------:|----------:|------:|-------:|----------:|------------:|
+| ExecuteStrategyPipeline_V7 | 2.275 μs | 0.0221 μs | 0.0309 μs | 1.00 | 0.1106 | 2824 B | 1.00 |
+| ExecuteStrategyPipeline_V8 | 1.759 μs | 0.0078 μs | 0.0114 μs | 0.77 | 0.0019 | 72 B | 0.03 |
diff --git a/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.PipelineBenchmark-report-github.md b/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.PipelineBenchmark-report-github.md
new file mode 100644
index 00000000000..7b797020006
--- /dev/null
+++ b/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.PipelineBenchmark-report-github.md
@@ -0,0 +1,24 @@
+``` ini
+
+BenchmarkDotNet=v0.13.5, OS=Windows 11 (10.0.22621.1702/22H2/2022Update/SunValley2), VM=Hyper-V
+Intel Xeon Platinum 8370C CPU 2.80GHz, 1 CPU, 16 logical and 8 physical cores
+.NET SDK=7.0.302
+ [Host] : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2
+
+Job=MediumRun Toolchain=InProcessEmitToolchain IterationCount=15
+LaunchCount=2 WarmupCount=10
+
+```
+| Method | Components | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
+|------------------- |----------- |-----------:|---------:|---------:|------:|--------:|-------:|----------:|------------:|
+| **ExecutePipeline_V7** | **1** | **112.6 ns** | **3.90 ns** | **5.83 ns** | **1.00** | **0.00** | **0.0120** | **304 B** | **1.00** |
+| ExecutePipeline_V8 | 1 | 114.7 ns | 1.43 ns | 2.14 ns | 1.02 | 0.06 | - | - | 0.00 |
+| | | | | | | | | | |
+| **ExecutePipeline_V7** | **2** | **281.6 ns** | **4.78 ns** | **7.15 ns** | **1.00** | **0.00** | **0.0219** | **552 B** | **1.00** |
+| ExecutePipeline_V8 | 2 | 155.8 ns | 1.00 ns | 1.50 ns | 0.55 | 0.02 | - | - | 0.00 |
+| | | | | | | | | | |
+| **ExecutePipeline_V7** | **5** | **921.0 ns** | **6.42 ns** | **9.00 ns** | **1.00** | **0.00** | **0.0515** | **1296 B** | **1.00** |
+| ExecutePipeline_V8 | 5 | 346.5 ns | 1.09 ns | 1.53 ns | 0.38 | 0.00 | - | - | 0.00 |
+| | | | | | | | | | |
+| **ExecutePipeline_V7** | **10** | **1,982.9 ns** | **63.37 ns** | **86.74 ns** | **1.00** | **0.00** | **0.0992** | **2536 B** | **1.00** |
+| ExecutePipeline_V8 | 10 | 610.2 ns | 3.49 ns | 5.01 ns | 0.31 | 0.01 | - | - | 0.00 |
diff --git a/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.RateLimiterBenchmark-report-github.md b/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.RateLimiterBenchmark-report-github.md
new file mode 100644
index 00000000000..187cfe9ab7d
--- /dev/null
+++ b/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.RateLimiterBenchmark-report-github.md
@@ -0,0 +1,15 @@
+``` ini
+
+BenchmarkDotNet=v0.13.5, OS=Windows 11 (10.0.22621.1702/22H2/2022Update/SunValley2), VM=Hyper-V
+Intel Xeon Platinum 8370C CPU 2.80GHz, 1 CPU, 16 logical and 8 physical cores
+.NET SDK=7.0.302
+ [Host] : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2
+
+Job=MediumRun Toolchain=InProcessEmitToolchain IterationCount=15
+LaunchCount=2 WarmupCount=10
+
+```
+| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
+|---------------------- |---------:|--------:|--------:|------:|--------:|-------:|----------:|------------:|
+| ExecuteRateLimiter_V7 | 250.8 ns | 3.45 ns | 5.06 ns | 1.00 | 0.00 | 0.0148 | 376 B | 1.00 |
+| ExecuteRateLimiter_V8 | 264.8 ns | 1.69 ns | 2.48 ns | 1.06 | 0.03 | 0.0014 | 40 B | 0.11 |
diff --git a/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.ResilienceStrategyBenchmark-report-github.md b/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.ResilienceStrategyBenchmark-report-github.md
new file mode 100644
index 00000000000..b1a8e63f55d
--- /dev/null
+++ b/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.ResilienceStrategyBenchmark-report-github.md
@@ -0,0 +1,16 @@
+``` ini
+
+BenchmarkDotNet=v0.13.5, OS=Windows 11 (10.0.22621.1702/22H2/2022Update/SunValley2), VM=Hyper-V
+Intel Xeon Platinum 8370C CPU 2.80GHz, 1 CPU, 16 logical and 8 physical cores
+.NET SDK=7.0.302
+ [Host] : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2
+
+Job=MediumRun Toolchain=InProcessEmitToolchain IterationCount=15
+LaunchCount=2 WarmupCount=10
+
+```
+| Method | Mean | Error | StdDev | Ratio | RatioSD | Allocated | Alloc Ratio |
+|----------------------------------------------- |----------:|---------:|---------:|------:|--------:|----------:|------------:|
+| ExecuteAsync_ResilienceContextAndState | 67.14 ns | 0.473 ns | 0.708 ns | 1.00 | 0.00 | - | NA |
+| ExecuteAsync_CancellationToken | 115.73 ns | 0.874 ns | 1.253 ns | 1.72 | 0.01 | - | NA |
+| ExecuteAsync_GenericStrategy_CancellationToken | 117.85 ns | 0.346 ns | 0.486 ns | 1.76 | 0.02 | - | NA |
diff --git a/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.RetryBenchmark-report-github.md b/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.RetryBenchmark-report-github.md
new file mode 100644
index 00000000000..773203665f9
--- /dev/null
+++ b/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.RetryBenchmark-report-github.md
@@ -0,0 +1,15 @@
+``` ini
+
+BenchmarkDotNet=v0.13.5, OS=Windows 11 (10.0.22621.1702/22H2/2022Update/SunValley2), VM=Hyper-V
+Intel Xeon Platinum 8370C CPU 2.80GHz, 1 CPU, 16 logical and 8 physical cores
+.NET SDK=7.0.302
+ [Host] : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2
+
+Job=MediumRun Toolchain=InProcessEmitToolchain IterationCount=15
+LaunchCount=2 WarmupCount=10
+
+```
+| Method | Mean | Error | StdDev | Median | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
+|---------------- |---------:|--------:|--------:|---------:|------:|--------:|-------:|----------:|------------:|
+| ExecuteRetry_V7 | 247.8 ns | 5.90 ns | 8.64 ns | 250.1 ns | 1.00 | 0.00 | 0.0219 | 552 B | 1.00 |
+| ExecuteRetry_V8 | 203.2 ns | 0.74 ns | 1.01 ns | 203.9 ns | 0.82 | 0.03 | - | - | 0.00 |
diff --git a/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.TimeoutBenchmark-report-github.md b/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.TimeoutBenchmark-report-github.md
new file mode 100644
index 00000000000..0c76c6b4c36
--- /dev/null
+++ b/src/Polly.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.TimeoutBenchmark-report-github.md
@@ -0,0 +1,15 @@
+``` ini
+
+BenchmarkDotNet=v0.13.5, OS=Windows 11 (10.0.22621.1702/22H2/2022Update/SunValley2), VM=Hyper-V
+Intel Xeon Platinum 8370C CPU 2.80GHz, 1 CPU, 16 logical and 8 physical cores
+.NET SDK=7.0.302
+ [Host] : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2
+
+Job=MediumRun Toolchain=InProcessEmitToolchain IterationCount=15
+LaunchCount=2 WarmupCount=10
+
+```
+| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
+|------------------ |---------:|--------:|--------:|------:|--------:|-------:|----------:|------------:|
+| ExecuteTimeout_V7 | 386.1 ns | 2.23 ns | 3.33 ns | 1.00 | 0.00 | 0.0286 | 728 B | 1.00 |
+| ExecuteTimeout_V8 | 300.2 ns | 4.65 ns | 6.95 ns | 0.78 | 0.02 | - | - | 0.00 |
diff --git a/src/Polly.Core.Benchmarks/Benchmarks/CircuitBreakerBenchmark.cs b/src/Polly.Core.Benchmarks/CircuitBreakerBenchmark.cs
similarity index 91%
rename from src/Polly.Core.Benchmarks/Benchmarks/CircuitBreakerBenchmark.cs
rename to src/Polly.Core.Benchmarks/CircuitBreakerBenchmark.cs
index 34b5dd6047b..2c670668b4a 100644
--- a/src/Polly.Core.Benchmarks/Benchmarks/CircuitBreakerBenchmark.cs
+++ b/src/Polly.Core.Benchmarks/CircuitBreakerBenchmark.cs
@@ -1,8 +1,7 @@
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
-using Polly.Core.Benchmarks;
-namespace Polly.Benchmarks;
+namespace Polly.Core.Benchmarks;
public class CircuitBreakerBenchmark
{
diff --git a/src/Polly.Core.Benchmarks/Benchmarks/GenericOverheadBenchmark.cs b/src/Polly.Core.Benchmarks/GenericOverheadBenchmark.cs
similarity index 97%
rename from src/Polly.Core.Benchmarks/Benchmarks/GenericOverheadBenchmark.cs
rename to src/Polly.Core.Benchmarks/GenericOverheadBenchmark.cs
index d92a6931016..9c2bb2fe583 100644
--- a/src/Polly.Core.Benchmarks/Benchmarks/GenericOverheadBenchmark.cs
+++ b/src/Polly.Core.Benchmarks/GenericOverheadBenchmark.cs
@@ -3,7 +3,7 @@
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
-namespace Polly.Benchmarks;
+namespace Polly.Core.Benchmarks;
public class GenericOverheadBenchmark
{
diff --git a/src/Polly.Core.Benchmarks/Benchmarks/HedgingBenchmark.cs b/src/Polly.Core.Benchmarks/HedgingBenchmark.cs
similarity index 97%
rename from src/Polly.Core.Benchmarks/Benchmarks/HedgingBenchmark.cs
rename to src/Polly.Core.Benchmarks/HedgingBenchmark.cs
index b121142d211..cc386044fa3 100644
--- a/src/Polly.Core.Benchmarks/Benchmarks/HedgingBenchmark.cs
+++ b/src/Polly.Core.Benchmarks/HedgingBenchmark.cs
@@ -2,7 +2,7 @@
using BenchmarkDotNet.Attributes;
using Polly.Core.Benchmarks;
-namespace Polly.Benchmarks;
+namespace Polly.Core.Benchmarks;
public class HedgingBenchmark
{
diff --git a/src/Polly.Core.Benchmarks/Benchmarks/StrategyPipelineBenchmark.cs b/src/Polly.Core.Benchmarks/MultipleStrategiesBenchmark.cs
similarity index 91%
rename from src/Polly.Core.Benchmarks/Benchmarks/StrategyPipelineBenchmark.cs
rename to src/Polly.Core.Benchmarks/MultipleStrategiesBenchmark.cs
index 26908933151..fa7b79b9750 100644
--- a/src/Polly.Core.Benchmarks/Benchmarks/StrategyPipelineBenchmark.cs
+++ b/src/Polly.Core.Benchmarks/MultipleStrategiesBenchmark.cs
@@ -1,9 +1,8 @@
using BenchmarkDotNet.Attributes;
-using Polly;
namespace Polly.Core.Benchmarks;
-public class StrategyPipelineBenchmark
+public class MultipleStrategiesBenchmark
{
private object? _strategyV7;
private object? _strategyV8;
diff --git a/src/Polly.Core.Benchmarks/Benchmarks/PipelineBenchmark.cs b/src/Polly.Core.Benchmarks/PipelineBenchmark.cs
similarity index 98%
rename from src/Polly.Core.Benchmarks/Benchmarks/PipelineBenchmark.cs
rename to src/Polly.Core.Benchmarks/PipelineBenchmark.cs
index 044d4e78d72..639ddd3ba6e 100644
--- a/src/Polly.Core.Benchmarks/Benchmarks/PipelineBenchmark.cs
+++ b/src/Polly.Core.Benchmarks/PipelineBenchmark.cs
@@ -1,5 +1,4 @@
using BenchmarkDotNet.Attributes;
-using Polly;
namespace Polly.Core.Benchmarks;
diff --git a/src/Polly.Core.Benchmarks/Polly.Core.Benchmarks.csproj b/src/Polly.Core.Benchmarks/Polly.Core.Benchmarks.csproj
index b6eebd6d2ea..748bef5ec47 100644
--- a/src/Polly.Core.Benchmarks/Polly.Core.Benchmarks.csproj
+++ b/src/Polly.Core.Benchmarks/Polly.Core.Benchmarks.csproj
@@ -2,7 +2,6 @@
net7.0
- Polly
true
Benchmark
enable
@@ -12,6 +11,7 @@
+
diff --git a/src/Polly.Core.Benchmarks/README.md b/src/Polly.Core.Benchmarks/README.md
index 50f34c547f7..8522847b9c5 100644
--- a/src/Polly.Core.Benchmarks/README.md
+++ b/src/Polly.Core.Benchmarks/README.md
@@ -1,81 +1,15 @@
-# Benchmark results
+# Benchmarks
-```text
-BenchmarkDotNet=v0.13.3, OS=Windows 11 (10.0.22621.1413)
-Intel Core i9-10885H CPU 2.40GHz, 1 CPU, 16 logical and 8 physical cores
-.NET SDK=7.0.202
- [Host] : .NET 7.0.4 (7.0.423.11508), X64 RyuJIT AVX2
+To run the benchmarks:
-Job=MediumRun Toolchain=InProcessEmitToolchain IterationCount=15
-LaunchCount=2 WarmupCount=10
-```
-
-## Genric vs Non-Generic classes
-
-This benchmark demonstrates that impact of having non-generic `ResilienceStrategy` is minimal.
-
-| Method | Mean | Error | StdDev | Ratio | Allocated | Alloc Ratio |
-|------------------------ |---------:|---------:|---------:|------:|----------:|------------:|
-| ExecuteAsync_Generic | 30.25 ns | 0.197 ns | 0.269 ns | 1.00 | - | NA |
-| ExecuteAsync_NonGeneric | 32.02 ns | 0.071 ns | 0.094 ns | 1.06 | - | NA |
-
-
-## PIPELINES
-
-| Method | Components | Mean | Error | StdDev | Median | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
-|------------------- |----------- |------------:|----------:|-----------:|------------:|------:|--------:|-------:|----------:|------------:|
-| ExecutePipeline_V7 | 1 | 74.78 ns | 1.555 ns | 2.279 ns | 75.63 ns | 1.00 | 0.00 | 0.0362 | 304 B | 1.00 |
-| ExecutePipeline_V8 | 1 | 85.69 ns | 0.500 ns | 0.732 ns | 85.36 ns | 1.15 | 0.04 | - | - | 0.00 |
-| | | | | | | | | | | |
-| ExecutePipeline_V7 | 2 | 165.37 ns | 1.157 ns | 1.732 ns | 165.59 ns | 1.00 | 0.00 | 0.0658 | 552 B | 1.00 |
-| ExecutePipeline_V8 | 2 | 119.10 ns | 0.653 ns | 0.915 ns | 119.63 ns | 0.72 | 0.01 | - | - | 0.00 |
-| | | | | | | | | | | |
-| ExecutePipeline_V7 | 5 | 533.97 ns | 7.327 ns | 10.967 ns | 536.79 ns | 1.00 | 0.00 | 0.1545 | 1296 B | 1.00 |
-| ExecutePipeline_V8 | 5 | 227.69 ns | 1.236 ns | 1.812 ns | 227.72 ns | 0.43 | 0.01 | - | - | 0.00 |
-| | | | | | | | | | | |
-| ExecutePipeline_V7 | 10 | 1,191.41 ns | 35.512 ns | 53.152 ns | 1,192.79 ns | 1.00 | 0.00 | 0.3014 | 2536 B | 1.00 |
-| ExecutePipeline_V8 | 10 | 557.95 ns | 76.434 ns | 112.036 ns | 505.58 ns | 0.47 | 0.09 | - | - | 0.00 |
-
-## TIMEOUT
-
-| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
-|------------------ |---------:|--------:|---------:|------:|--------:|-------:|----------:|------------:|
-| ExecuteTimeout_V7 | 304.9 ns | 7.53 ns | 11.27 ns | 1.00 | 0.00 | 0.0868 | 728 B | 1.00 |
-| ExecuteTimeout_V8 | 266.5 ns | 5.95 ns | 8.72 ns | 0.88 | 0.04 | - | - | 0.00 |
+``` powershell
+# run all benchmarks
+dotnet run -c release -f net7.0
-## RETRY
-
-| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
-|---------------- |---------:|--------:|--------:|------:|--------:|-------:|----------:|------------:|
-| ExecuteRetry_V7 | 169.8 ns | 4.98 ns | 6.98 ns | 1.00 | 0.00 | 0.0687 | 576 B | 1.00 |
-| ExecuteRetry_V8 | 144.9 ns | 2.35 ns | 3.52 ns | 0.85 | 0.04 | - | - | 0.00 |
-
-## RATE LIMITER
-
-| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
-|---------------------- |---------:|---------:|---------:|------:|--------:|-------:|----------:|------------:|
-| ExecuteRateLimiter_V7 | 190.8 ns | 10.01 ns | 14.98 ns | 1.00 | 0.00 | 0.0448 | 376 B | 1.00 |
-| ExecuteRateLimiter_V8 | 199.6 ns | 2.54 ns | 3.64 ns | 1.05 | 0.09 | 0.0048 | 40 B | 0.11 |
-
-## CIRCUIT BREAKER
-
-| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
-|------------------------- |---------:|--------:|--------:|------:|--------:|-------:|----------:|------------:|
-| ExecuteCircuitBreaker_V7 | 198.4 ns | 2.78 ns | 3.99 ns | 1.00 | 0.00 | 0.0629 | 528 B | 1.00 |
-| ExecuteCircuitBreaker_V8 | 297.9 ns | 2.63 ns | 3.77 ns | 1.50 | 0.04 | 0.0038 | 32 B | 0.06 |
-
-## STRATEGY PIPELINE (RATE LIMITER + TIMEOUT + RETRY + TIMEOUT + CIRCUIT BREAKER)
-
-| Method | Mean | Error | StdDev | Ratio | Gen0 | Allocated | Alloc Ratio |
-|--------------------------- |---------:|----------:|----------:|------:|-------:|----------:|------------:|
-| ExecuteStrategyPipeline_V7 | 1.523 us | 0.0092 us | 0.0137 us | 1.00 | 0.3433 | 2872 B | 1.00 |
-| ExecuteStrategyPipeline_V8 | 1.276 us | 0.0128 us | 0.0191 us | 0.84 | 0.0114 | 96 B | 0.03 |
+# pick benchmarks to run
+dotnet run -c release -f net7.0 -- pick
+```
-## HEDGING
+The benchmark results are stored in [`BenchmarkDotNet.Artifacts/results`](BenchmarkDotNet.Artifacts/results/) folder.
-| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Allocated | Alloc Ratio |
-|---------------------------- |-----------:|----------:|----------:|------:|--------:|-------:|-------:|----------:|------------:|
-| Hedging_Primary | 891.3 ns | 39.39 ns | 58.96 ns | 1.00 | 0.00 | 0.0048 | - | 40 B | 1.00 |
-| Hedging_Secondary | 1,500.0 ns | 7.88 ns | 11.80 ns | 1.69 | 0.11 | 0.0229 | - | 200 B | 5.00 |
-| Hedging_Primary_AsyncWork | 4,250.9 ns | 140.89 ns | 206.52 ns | 4.78 | 0.34 | 0.1831 | 0.0305 | 1518 B | 37.95 |
-| Hedging_Secondary_AsyncWork | 6,544.9 ns | 99.90 ns | 143.27 ns | 7.34 | 0.39 | 0.2213 | 0.0839 | 1872 B | 46.80 |
+Run the benchmarks when your changes are significant enough to make sense running them. We do not use fixed hardware so your numbers might differ, however the important is the `Ratio` and `Alloc Ratio` which stays around the same or improves (ideally) between runs.
diff --git a/src/Polly.Core.Benchmarks/Benchmarks/RateLimiterBenchmark.cs b/src/Polly.Core.Benchmarks/RateLimiterBenchmark.cs
similarity index 91%
rename from src/Polly.Core.Benchmarks/Benchmarks/RateLimiterBenchmark.cs
rename to src/Polly.Core.Benchmarks/RateLimiterBenchmark.cs
index 023a4f3397f..44cf5b9aeb4 100644
--- a/src/Polly.Core.Benchmarks/Benchmarks/RateLimiterBenchmark.cs
+++ b/src/Polly.Core.Benchmarks/RateLimiterBenchmark.cs
@@ -1,8 +1,7 @@
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
-using Polly.Core.Benchmarks;
-namespace Polly.Benchmarks;
+namespace Polly.Core.Benchmarks;
public class RateLimiterBenchmark
{
diff --git a/src/Polly.Core.Benchmarks/ResilienceStrategyBenchmark.cs b/src/Polly.Core.Benchmarks/ResilienceStrategyBenchmark.cs
new file mode 100644
index 00000000000..31b18a08095
--- /dev/null
+++ b/src/Polly.Core.Benchmarks/ResilienceStrategyBenchmark.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Runtime.CompilerServices;
+using System.Threading.Tasks;
+using BenchmarkDotNet.Attributes;
+using Polly.Strategy;
+
+namespace Polly.Core.Benchmarks;
+
+public class ResilienceStrategyBenchmark
+{
+ private readonly DummyResilienceStrategy _strategy = new();
+ private readonly ResilienceStrategy _genericStrategy = NullResilienceStrategy.Instance;
+
+ [Benchmark(Baseline = true)]
+ public async ValueTask ExecuteAsync_ResilienceContextAndState()
+ {
+ var context = ResilienceContext.Get();
+ await _strategy.ExecuteAsync((_, _) => new ValueTask>(new Outcome("dummy")), context, "state").ConfigureAwait(false);
+ ResilienceContext.Return(context);
+ }
+
+ [Benchmark]
+ public async ValueTask ExecuteAsync_CancellationToken()
+ {
+ await _strategy.ExecuteAsync(_ => new ValueTask("dummy"), CancellationToken.None).ConfigureAwait(false);
+ }
+
+ [Benchmark]
+ public async ValueTask ExecuteAsync_GenericStrategy_CancellationToken()
+ {
+ await _genericStrategy.ExecuteAsync(_ => new ValueTask("dummy"), CancellationToken.None).ConfigureAwait(false);
+ }
+
+ private class DummyResilienceStrategy : ResilienceStrategy
+ {
+ protected override ValueTask ExecuteCoreAsync(
+ Func> callback,
+ ResilienceContext context,
+ TState state) => callback(context, state);
+ }
+
+ public class NonGenericStrategy
+ {
+ [MethodImpl(MethodImplOptions.NoOptimization)]
+ public virtual ValueTask ExecuteAsync(Func> callback)
+ {
+ return callback();
+ }
+ }
+}
diff --git a/src/Polly.Core.Benchmarks/Benchmarks/RetryBenchmark.cs b/src/Polly.Core.Benchmarks/RetryBenchmark.cs
similarity index 90%
rename from src/Polly.Core.Benchmarks/Benchmarks/RetryBenchmark.cs
rename to src/Polly.Core.Benchmarks/RetryBenchmark.cs
index 2c9e3363465..3e8e8b45e06 100644
--- a/src/Polly.Core.Benchmarks/Benchmarks/RetryBenchmark.cs
+++ b/src/Polly.Core.Benchmarks/RetryBenchmark.cs
@@ -1,8 +1,7 @@
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
-using Polly.Core.Benchmarks;
-namespace Polly.Benchmarks;
+namespace Polly.Core.Benchmarks;
public class RetryBenchmark
{
diff --git a/src/Polly.Core.Benchmarks/Benchmarks/TimeoutBenchmark.cs b/src/Polly.Core.Benchmarks/TimeoutBenchmark.cs
similarity index 90%
rename from src/Polly.Core.Benchmarks/Benchmarks/TimeoutBenchmark.cs
rename to src/Polly.Core.Benchmarks/TimeoutBenchmark.cs
index 5b85f3f81e7..df09bec7ea0 100644
--- a/src/Polly.Core.Benchmarks/Benchmarks/TimeoutBenchmark.cs
+++ b/src/Polly.Core.Benchmarks/TimeoutBenchmark.cs
@@ -1,8 +1,7 @@
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
-using Polly.Core.Benchmarks;
-namespace Polly.Benchmarks;
+namespace Polly.Core.Benchmarks;
public class TimeoutBenchmark
{
diff --git a/src/Polly.Core.Benchmarks/Internals/EmptyResilienceStrategy.cs b/src/Polly.Core.Benchmarks/Utils/EmptyResilienceStrategy.cs
similarity index 86%
rename from src/Polly.Core.Benchmarks/Internals/EmptyResilienceStrategy.cs
rename to src/Polly.Core.Benchmarks/Utils/EmptyResilienceStrategy.cs
index 07929ab6f74..3e7727ff9ae 100644
--- a/src/Polly.Core.Benchmarks/Internals/EmptyResilienceStrategy.cs
+++ b/src/Polly.Core.Benchmarks/Utils/EmptyResilienceStrategy.cs
@@ -1,6 +1,4 @@
-using Polly;
-
-namespace Polly.Core.Benchmarks;
+namespace Polly.Core.Benchmarks.Utils;
internal class EmptyResilienceStrategy : ResilienceStrategy
{
diff --git a/src/Polly.Core.Benchmarks/Internals/Helper.CircuitBreaker.cs b/src/Polly.Core.Benchmarks/Utils/Helper.CircuitBreaker.cs
similarity index 96%
rename from src/Polly.Core.Benchmarks/Internals/Helper.CircuitBreaker.cs
rename to src/Polly.Core.Benchmarks/Utils/Helper.CircuitBreaker.cs
index 24f77d2f3e8..d444854d191 100644
--- a/src/Polly.Core.Benchmarks/Internals/Helper.CircuitBreaker.cs
+++ b/src/Polly.Core.Benchmarks/Utils/Helper.CircuitBreaker.cs
@@ -1,7 +1,7 @@
using System;
using Polly.CircuitBreaker;
-namespace Polly.Core.Benchmarks;
+namespace Polly.Core.Benchmarks.Utils;
internal static partial class Helper
{
diff --git a/src/Polly.Core.Benchmarks/Internals/Helper.Hedging.cs b/src/Polly.Core.Benchmarks/Utils/Helper.Hedging.cs
similarity index 93%
rename from src/Polly.Core.Benchmarks/Internals/Helper.Hedging.cs
rename to src/Polly.Core.Benchmarks/Utils/Helper.Hedging.cs
index f2a9a8b1941..74e09e43c92 100644
--- a/src/Polly.Core.Benchmarks/Internals/Helper.Hedging.cs
+++ b/src/Polly.Core.Benchmarks/Utils/Helper.Hedging.cs
@@ -1,7 +1,7 @@
using Polly.Hedging;
using Polly.Strategy;
-namespace Polly.Core.Benchmarks;
+namespace Polly.Core.Benchmarks.Utils;
internal static partial class Helper
{
diff --git a/src/Polly.Core.Benchmarks/Internals/Helper.Pipeline.cs b/src/Polly.Core.Benchmarks/Utils/Helper.MultipleStrategies.cs
similarity index 97%
rename from src/Polly.Core.Benchmarks/Internals/Helper.Pipeline.cs
rename to src/Polly.Core.Benchmarks/Utils/Helper.MultipleStrategies.cs
index b7584025103..6f5be5454f7 100644
--- a/src/Polly.Core.Benchmarks/Internals/Helper.Pipeline.cs
+++ b/src/Polly.Core.Benchmarks/Utils/Helper.MultipleStrategies.cs
@@ -1,8 +1,7 @@
using System.Threading.RateLimiting;
-using Polly;
using Polly.Strategy;
-namespace Polly.Core.Benchmarks;
+namespace Polly.Core.Benchmarks.Utils;
internal static partial class Helper
{
diff --git a/src/Polly.Core.Benchmarks/Internals/Helper.RateLimiting.cs b/src/Polly.Core.Benchmarks/Utils/Helper.RateLimiting.cs
similarity index 94%
rename from src/Polly.Core.Benchmarks/Internals/Helper.RateLimiting.cs
rename to src/Polly.Core.Benchmarks/Utils/Helper.RateLimiting.cs
index 8c9fd06602d..8970881477a 100644
--- a/src/Polly.Core.Benchmarks/Internals/Helper.RateLimiting.cs
+++ b/src/Polly.Core.Benchmarks/Utils/Helper.RateLimiting.cs
@@ -3,7 +3,7 @@
using System;
using System.Threading.RateLimiting;
-namespace Polly.Core.Benchmarks;
+namespace Polly.Core.Benchmarks.Utils;
internal static partial class Helper
{
diff --git a/src/Polly.Core.Benchmarks/Internals/Helper.Retry.cs b/src/Polly.Core.Benchmarks/Utils/Helper.Retry.cs
similarity index 96%
rename from src/Polly.Core.Benchmarks/Internals/Helper.Retry.cs
rename to src/Polly.Core.Benchmarks/Utils/Helper.Retry.cs
index 55b32b3386b..06cdd218c25 100644
--- a/src/Polly.Core.Benchmarks/Internals/Helper.Retry.cs
+++ b/src/Polly.Core.Benchmarks/Utils/Helper.Retry.cs
@@ -1,6 +1,6 @@
using System;
-namespace Polly.Core.Benchmarks;
+namespace Polly.Core.Benchmarks.Utils;
internal static partial class Helper
{
diff --git a/src/Polly.Core.Benchmarks/Internals/Helper.StrategyPipeline.cs b/src/Polly.Core.Benchmarks/Utils/Helper.StrategyPipeline.cs
similarity index 92%
rename from src/Polly.Core.Benchmarks/Internals/Helper.StrategyPipeline.cs
rename to src/Polly.Core.Benchmarks/Utils/Helper.StrategyPipeline.cs
index f7f80b6975f..8156caadd94 100644
--- a/src/Polly.Core.Benchmarks/Internals/Helper.StrategyPipeline.cs
+++ b/src/Polly.Core.Benchmarks/Utils/Helper.StrategyPipeline.cs
@@ -1,6 +1,4 @@
-using Polly;
-
-namespace Polly.Core.Benchmarks;
+namespace Polly.Core.Benchmarks.Utils;
internal static partial class Helper
{
diff --git a/src/Polly.Core.Benchmarks/Internals/Helper.Timeout.cs b/src/Polly.Core.Benchmarks/Utils/Helper.Timeout.cs
similarity index 80%
rename from src/Polly.Core.Benchmarks/Internals/Helper.Timeout.cs
rename to src/Polly.Core.Benchmarks/Utils/Helper.Timeout.cs
index 67fc4e7d609..f86d3230f4d 100644
--- a/src/Polly.Core.Benchmarks/Internals/Helper.Timeout.cs
+++ b/src/Polly.Core.Benchmarks/Utils/Helper.Timeout.cs
@@ -2,7 +2,7 @@
using System;
-namespace Polly.Core.Benchmarks;
+namespace Polly.Core.Benchmarks.Utils;
internal static partial class Helper
{
@@ -12,7 +12,7 @@ public static object CreateTimeout(PollyVersion technology)
return technology switch
{
- PollyVersion.V7 => Policy.TimeoutAsync(timeout),
+ PollyVersion.V7 => Policy.TimeoutAsync(timeout),
PollyVersion.V8 => CreateStrategy(builder => builder.AddTimeout(timeout)),
_ => throw new NotSupportedException()
};
diff --git a/src/Polly.Core.Benchmarks/Internals/Helper.cs b/src/Polly.Core.Benchmarks/Utils/Helper.cs
similarity index 96%
rename from src/Polly.Core.Benchmarks/Internals/Helper.cs
rename to src/Polly.Core.Benchmarks/Utils/Helper.cs
index 790b997e119..965dedbd0e7 100644
--- a/src/Polly.Core.Benchmarks/Internals/Helper.cs
+++ b/src/Polly.Core.Benchmarks/Utils/Helper.cs
@@ -1,6 +1,6 @@
#pragma warning disable S4225 // Extension methods should not extend "object"
-namespace Polly.Core.Benchmarks;
+namespace Polly.Core.Benchmarks.Utils;
internal static partial class Helper
{