Skip to content

Commit

Permalink
Introduce Polly.Core.Benchmark (#1061)
Browse files Browse the repository at this point in the history
  • Loading branch information
martintmk authored Mar 18, 2023
1 parent f314ce3 commit 66ca902
Show file tree
Hide file tree
Showing 13 changed files with 5,585 additions and 2 deletions.
9 changes: 9 additions & 0 deletions eng/Benchmark.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project>

<Import Project="..\Version.props" />

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.3" />
</ItemGroup>

</Project>
5,396 changes: 5,396 additions & 0 deletions eng/analyzers/Benchmark.globalconfig

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<Project>
<Import Project="$(MsBuildThisFileDirectory)../eng/Common.targets" />
<Import Project="$(MsBuildThisFileDirectory)../eng/Test.targets" Condition="$(ProjectType) == 'Test'" />
<Import Project="$(MsBuildThisFileDirectory)../eng/Library.targets" Condition="$(ProjectType) == 'Library'" />
<Import Project="$(MsBuildThisFileDirectory)../eng/$(ProjectType).targets" Condition="$(ProjectType) != ''" />

</Project>
31 changes: 31 additions & 0 deletions src/Polly.Core.Benchmarks/Benchmarks/PipelineBenchmark.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using BenchmarkDotNet.Attributes;
using Polly;

namespace Polly.Core.Benchmarks;

public class PipelineBenchmark
{
private object? _strategyV7;
private object? _strategyV8;
private object? _strategyV8Delegating;

[GlobalSetup]
public void Setup()
{
_strategyV7 = Helper.CreatePipeline(PollyVersion.V7, Components, delegating: false);
_strategyV8 = Helper.CreatePipeline(PollyVersion.V8, Components, delegating: false);
_strategyV8Delegating = Helper.CreatePipeline(PollyVersion.V8, Components, delegating: true);
}

[Params(1, 2, 5, 10)]
public int Components { get; set; }

[Benchmark(Baseline = true)]
public ValueTask ExecutePipeline_V7() => _strategyV7!.ExecuteAsync(PollyVersion.V7);

[Benchmark]
public ValueTask ExecutePipeline_V8() => _strategyV8!.ExecuteAsync(PollyVersion.V8);

[Benchmark]
public ValueTask ExecutePipeline_V8Delegating() => _strategyV8Delegating!.ExecuteAsync(PollyVersion.V8);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Polly.Core.Benchmarks;

internal class EmptyDelegatingResilienceStrategy : DelegatingResilienceStrategy
{
protected override ValueTask<TResult> ExecuteCoreAsync<TResult, TState>(Func<ResilienceContext, TState, ValueTask<TResult>> callback, ResilienceContext context, TState state)
{
return base.ExecuteCoreAsync(callback, context, state);
}
}
11 changes: 11 additions & 0 deletions src/Polly.Core.Benchmarks/Internals/EmptyResilienceStrategy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Polly;

namespace Polly.Core.Benchmarks;

internal class EmptyResilienceStrategy : ResilienceStrategy
{
protected override ValueTask<TResult> ExecuteCoreAsync<TResult, TState>(Func<ResilienceContext, TState, ValueTask<TResult>> callback, ResilienceContext context, TState state)
{
return callback(context, state);
}
}
20 changes: 20 additions & 0 deletions src/Polly.Core.Benchmarks/Internals/Helper.Pipeline.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Polly;

namespace Polly.Core.Benchmarks;

internal static partial class Helper
{
public static object CreatePipeline(PollyVersion technology, int count, bool delegating) => technology switch
{
PollyVersion.V7 => count == 1 ? Policy.NoOpAsync<int>() : Policy.WrapAsync(Enumerable.Repeat(0, count).Select(_ => Policy.NoOpAsync<int>()).ToArray()),

PollyVersion.V8 => CreateStrategy(builder =>
{
for (var i = 0; i < count; i++)
{
builder.AddStrategy(delegating ? new EmptyDelegatingResilienceStrategy() : new EmptyResilienceStrategy());
}
}),
_ => throw new NotSupportedException()
};
}
31 changes: 31 additions & 0 deletions src/Polly.Core.Benchmarks/Internals/Helper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Polly;
using Polly.Builder;

#pragma warning disable S4225 // Extension methods should not extend "object"

namespace Polly.Core.Benchmarks;

internal static partial class Helper
{
public static async ValueTask ExecuteAsync(this object obj, PollyVersion version)
{
switch (version)
{
case PollyVersion.V7:
await ((IAsyncPolicy<int>)obj).ExecuteAsync(static _ => Task.FromResult(999), CancellationToken.None).ConfigureAwait(false);
return;
case PollyVersion.V8:
await ((ResilienceStrategy)obj).ExecuteValueTaskAsync(static _ => new ValueTask<int>(999), CancellationToken.None).ConfigureAwait(false);
return;
}

throw new NotSupportedException();
}

private static ResilienceStrategy CreateStrategy(Action<ResilienceStrategyBuilder> configure)
{
var builder = new ResilienceStrategyBuilder();
configure(builder);
return builder.Build();
}
}
19 changes: 19 additions & 0 deletions src/Polly.Core.Benchmarks/Polly.Core.Benchmarks.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net7.0</TargetFrameworks>
<RootNamespace>Polly</RootNamespace>
<ImplicitUsings>true</ImplicitUsings>
<ProjectType>Benchmark</ProjectType>
<Nullable>enable</Nullable>
<OutputType>Exe</OutputType>
<UseDefaultAnalyzers>true</UseDefaultAnalyzers>
<NoWarn>$(NoWarn);SA1600</NoWarn>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Polly.Core\Polly.Core.csproj" />
<ProjectReference Include="..\Polly\Polly.csproj" />
</ItemGroup>

</Project>
7 changes: 7 additions & 0 deletions src/Polly.Core.Benchmarks/PollyVersion.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Polly.Core.Benchmarks;

public enum PollyVersion
{
V7,
V8
}
13 changes: 13 additions & 0 deletions src/Polly.Core.Benchmarks/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Toolchains.InProcess.Emit;
using Polly.Core.Benchmarks;

var config = ManualConfig
.Create(DefaultConfig.Instance)
.AddJob(Job.MediumRun.WithToolchain(InProcessEmitToolchain.Instance))
.AddDiagnoser(MemoryDiagnoser.Default);

BenchmarkRunner.Run(typeof(PollyVersion).Assembly, config);
31 changes: 31 additions & 0 deletions src/Polly.Core.Benchmarks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Benchmark results

```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
Job=MediumRun Toolchain=InProcessEmitToolchain IterationCount=15
LaunchCount=2 WarmupCount=10
```

## PIPELINES

| Method | Components | Mean | Error | StdDev | Median | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
|----------------------------- |----------- |------------:|----------:|----------:|------------:|------:|--------:|-------:|----------:|------------:|
| ExecutePipeline_V7 | 1 | 74.84 ns | 1.279 ns | 1.835 ns | 75.81 ns | 1.00 | 0.00 | 0.0362 | 304 B | 1.00 |
| ExecutePipeline_V8 | 1 | 72.61 ns | 0.584 ns | 0.819 ns | 72.28 ns | 0.97 | 0.02 | 0.0048 | 40 B | 0.13 |
| ExecutePipeline_V8Delegating | 1 | 90.04 ns | 0.753 ns | 1.104 ns | 89.76 ns | 1.20 | 0.02 | 0.0048 | 40 B | 0.13 |
| | | | | | | | | | | |
| ExecutePipeline_V7 | 2 | 156.67 ns | 2.810 ns | 4.119 ns | 154.12 ns | 1.00 | 0.00 | 0.0658 | 552 B | 1.00 |
| ExecutePipeline_V8 | 2 | 185.87 ns | 1.932 ns | 2.580 ns | 185.02 ns | 1.19 | 0.04 | 0.0048 | 40 B | 0.07 |
| ExecutePipeline_V8Delegating | 2 | 127.92 ns | 1.264 ns | 1.772 ns | 129.00 ns | 0.82 | 0.02 | 0.0048 | 40 B | 0.07 |
| | | | | | | | | | | |
| ExecutePipeline_V7 | 5 | 543.85 ns | 19.540 ns | 29.247 ns | 530.00 ns | 1.00 | 0.00 | 0.1545 | 1296 B | 1.00 |
| ExecutePipeline_V8 | 5 | 335.67 ns | 3.903 ns | 5.598 ns | 336.22 ns | 0.62 | 0.04 | 0.0048 | 40 B | 0.03 |
| ExecutePipeline_V8Delegating | 5 | 189.99 ns | 4.045 ns | 5.929 ns | 189.05 ns | 0.35 | 0.02 | 0.0048 | 40 B | 0.03 |
| | | | | | | | | | | |
| ExecutePipeline_V7 | 10 | 1,112.84 ns | 8.585 ns | 12.036 ns | 1,111.96 ns | 1.00 | 0.00 | 0.3014 | 2536 B | 1.00 |
| ExecutePipeline_V8 | 10 | 543.85 ns | 6.205 ns | 9.095 ns | 545.30 ns | 0.49 | 0.01 | 0.0048 | 40 B | 0.02 |
| ExecutePipeline_V8Delegating | 10 | 258.11 ns | 0.881 ns | 1.318 ns | 258.30 ns | 0.23 | 0.00 | 0.0048 | 40 B | 0.02 |
6 changes: 6 additions & 0 deletions src/Polly.sln
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "eng", "eng", "{04E3C7C5-31F
..\eng\Test.targets = ..\eng\Test.targets
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Polly.Core.Benchmarks", "Polly.Core.Benchmarks\Polly.Core.Benchmarks.csproj", "{CC306C35-E3BC-4F0B-AB8C-B9D4C82DC3DE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -60,6 +62,10 @@ Global
{AF1383E7-BABF-492A-91C8-F2789AE7B3B4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AF1383E7-BABF-492A-91C8-F2789AE7B3B4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AF1383E7-BABF-492A-91C8-F2789AE7B3B4}.Release|Any CPU.Build.0 = Release|Any CPU
{CC306C35-E3BC-4F0B-AB8C-B9D4C82DC3DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CC306C35-E3BC-4F0B-AB8C-B9D4C82DC3DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CC306C35-E3BC-4F0B-AB8C-B9D4C82DC3DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CC306C35-E3BC-4F0B-AB8C-B9D4C82DC3DE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down

0 comments on commit 66ca902

Please sign in to comment.