Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion benchmarks/Benchmark.Behaviors/Benchmark.Behaviors.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
Expand Down
82 changes: 50 additions & 32 deletions benchmarks/Benchmark.Behaviors/Benchmark.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Order;
using Immediate.Handlers.Shared;
Expand All @@ -7,7 +8,7 @@
namespace Immediate.Handlers.Benchmarks;

public sealed class DirectTimingBehavior(
SomeHandlerClass handler
TraditionalExample handler
)
{
public TimeSpan Elapsed { get; private set; }
Expand Down Expand Up @@ -81,21 +82,15 @@ public sealed class SomeService
{
private static readonly SomeResponse s_response = new(Guid.NewGuid());

private static ValueTask<SomeResponse> VtResponse => new(s_response);

[System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Bench instance method")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Not Being Tested")]
[SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Bench instance method")]
[SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Not Being Tested")]
public ValueTask<SomeResponse> ServiceHandler(
SomeRequest request,
CancellationToken cancellationToken
) => VtResponse;
) => ValueTask.FromResult(s_response);
}

[Handler]
[Behaviors(
typeof(IhTimingBehavior<,>)
)]
public sealed partial class SomeHandlerClass(SomeService service)
public sealed partial class TraditionalExample(SomeService service)
: Mediator.IRequestHandler<SomeRequest, SomeResponse>,
MediatR.IRequestHandler<SomeRequest, SomeResponse>
{
Expand All @@ -113,37 +108,53 @@ async Task<SomeResponse> MediatR.IRequestHandler<SomeRequest, SomeResponse>.Hand
SomeRequest request,
CancellationToken cancellationToken
) => await service.ServiceHandler(request, cancellationToken);
}

[Handler]
[Behaviors(
typeof(IhTimingBehavior<,>)
)]
public static partial class StaticIhExample
{
private static async ValueTask<SomeResponse> HandleAsync(
SomeRequest request,
SomeService service,
CancellationToken cancellationToken
) => await service.ServiceHandler(request, cancellationToken);
}

[Handler]
[Behaviors(
typeof(IhTimingBehavior<,>)
)]
public sealed partial class SealedIhExample(SomeService service)
{
private async ValueTask<SomeResponse> HandleAsync(
SomeRequest request,
CancellationToken cancellationToken
) => await service.ServiceHandler(request, cancellationToken);
}

[MemoryDiagnoser]
[Orderer(SummaryOrderPolicy.FastestToSlowest, MethodOrderPolicy.Declared)]
[RankColumn]
//[EventPipeProfiler(EventPipeProfile.CpuSampling)]
//[DisassemblyDiagnoser]
//[InliningDiagnoser(logFailuresOnly: true, allowedNamespaces: new[] { "Mediator" })]
#pragma warning disable CA1707 // Identifiers should not contain underscores
public class RequestBenchmarks
{
private IServiceProvider? _serviceProvider;
private IServiceProvider? _abstractionServiceProvider;
private IServiceScope? _serviceScope;
private IServiceScope? _abstractionServiceScope;
private Mediator.IMediator? _mediator;
private Mediator.Mediator? _concreteMediator;
private MediatR.IMediator? _mediatr;
private SomeHandlerClass.Handler? _immediateHandler;
private IHandler<SomeRequest, SomeResponse>? _immediateHandlerAbstraction;
private DirectTimingBehavior? _handler;
private SomeRequest? _request;

[GlobalSetup]
public void Setup()
private readonly IServiceProvider _serviceProvider;
private readonly IServiceProvider _abstractionServiceProvider;
private readonly IServiceScope _serviceScope;
private readonly IServiceScope _abstractionServiceScope;
private readonly Mediator.IMediator _mediator;
private readonly Mediator.Mediator _concreteMediator;
private readonly MediatR.IMediator _mediatr;
private readonly StaticIhExample.Handler _immediateStaticHandler;
private readonly SealedIhExample.Handler _immediateSealedHandler;
private readonly IHandler<SomeRequest, SomeResponse> _immediateHandlerAbstraction;
private readonly DirectTimingBehavior _handler;
private readonly SomeRequest _request;

public RequestBenchmarks()
{
var services = new ServiceCollection();

Expand All @@ -167,7 +178,7 @@ public void Setup()
);

_ = services.AddScoped<DirectTimingBehavior>();
_ = services.AddScoped<SomeHandlerClass>();
_ = services.AddScoped<TraditionalExample>();

_serviceProvider = services.BuildServiceProvider();

Expand All @@ -177,7 +188,8 @@ public void Setup()
_mediator = _serviceProvider.GetRequiredService<Mediator.IMediator>();
_concreteMediator = _serviceProvider.GetRequiredService<Mediator.Mediator>();
_mediatr = _serviceProvider.GetRequiredService<MediatR.IMediator>();
_immediateHandler = _serviceProvider.GetRequiredService<SomeHandlerClass.Handler>();
_immediateStaticHandler = _serviceProvider.GetRequiredService<StaticIhExample.Handler>();
_immediateSealedHandler = _serviceProvider.GetRequiredService<SealedIhExample.Handler>();
_handler = _serviceProvider.GetRequiredService<DirectTimingBehavior>();
_request = new(Guid.NewGuid());

Expand All @@ -201,9 +213,15 @@ public void Cleanup()
}

[Benchmark]
public ValueTask<SomeResponse> SendRequest_ImmediateHandler()
public ValueTask<SomeResponse> SendRequest_ImmediateStaticHandler()
{
return _immediateStaticHandler!.HandleAsync(_request!, CancellationToken.None);
}

[Benchmark]
public ValueTask<SomeResponse> SendRequest_ImmediateSealedHandler()
{
return _immediateHandler!.HandleAsync(_request!, CancellationToken.None);
return _immediateSealedHandler!.HandleAsync(_request!, CancellationToken.None);
}

[Benchmark]
Expand Down
59 changes: 40 additions & 19 deletions benchmarks/Benchmark.Large/Benchmark.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Order;
using Immediate.Handlers.Shared;
Expand All @@ -11,46 +12,58 @@ public sealed record SomeRequest(Guid Id)

public sealed record SomeResponse(Guid Id);

[Handler]
public sealed partial class SomeHandlerClass
: Mediator.IRequestHandler<SomeRequest, SomeResponse>,
MediatR.IRequestHandler<SomeRequest, SomeResponse>
{
private static readonly SomeResponse s_response = new(Guid.NewGuid());

private static readonly Task<SomeResponse> s_tResponse = Task.FromResult(s_response);
private static ValueTask<SomeResponse> VtResponse => new(s_response);

[System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Bench instance method")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Not Being Tested")]
[SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Bench instance method")]
[SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Not Being Tested")]
public ValueTask<SomeResponse> Handle(
SomeRequest request,
CancellationToken cancellationToken
) => VtResponse;
) => ValueTask.FromResult(s_response);

ValueTask<SomeResponse> Mediator.IRequestHandler<SomeRequest, SomeResponse>.Handle(
SomeRequest request,
CancellationToken cancellationToken
) => VtResponse;
) => ValueTask.FromResult(s_response);

Task<SomeResponse> MediatR.IRequestHandler<SomeRequest, SomeResponse>.Handle(
SomeRequest request,
CancellationToken cancellationToken
) => s_tResponse;
) => Task.FromResult(s_response);
}

[Handler]
public static partial class StaticIhExample
{
private static readonly SomeResponse s_response = new(Guid.NewGuid());

[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Not Being Tested")]
[SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Not Being Tested")]
private static ValueTask<SomeResponse> HandleAsync(
SomeRequest request,
CancellationToken cancellationToken
) => VtResponse;
CancellationToken token
) => ValueTask.FromResult(s_response);
}

[Handler]
public sealed partial class SealedIhExample
{
private static readonly SomeResponse s_response = new(Guid.NewGuid());

[SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Not Being Tested")]
[SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Bench instance method")]
private ValueTask<SomeResponse> HandleAsync(
SomeRequest request,
CancellationToken token
) => ValueTask.FromResult(s_response);
}

[MemoryDiagnoser]
[Orderer(SummaryOrderPolicy.FastestToSlowest, MethodOrderPolicy.Declared)]
[RankColumn]
//[EventPipeProfiler(EventPipeProfile.CpuSampling)]
//[DisassemblyDiagnoser]
//[InliningDiagnoser(logFailuresOnly: true, allowedNamespaces: new[] { "Mediator" })]
#pragma warning disable CA1707 // Identifiers should not contain underscores
public class RequestBenchmarks
{
Expand All @@ -61,7 +74,8 @@ public class RequestBenchmarks
private Mediator.IMediator? _mediator;
private Mediator.Mediator? _concreteMediator;
private MediatR.IMediator? _mediatr;
private SomeHandlerClass.Handler? _immediateHandler;
private StaticIhExample.Handler? _immediateStaticHandler;
private SealedIhExample.Handler? _immediateSealedHandler;
private IHandler<SomeRequest, SomeResponse>? _immediateHandlerAbstraction;
private SomeHandlerClass? _handler;
private SomeRequest? _request;
Expand All @@ -86,7 +100,8 @@ public void Setup()
_mediator = _serviceProvider.GetRequiredService<Mediator.IMediator>();
_concreteMediator = _serviceProvider.GetRequiredService<Mediator.Mediator>();
_mediatr = _serviceProvider.GetRequiredService<MediatR.IMediator>();
_immediateHandler = _serviceProvider.GetRequiredService<SomeHandlerClass.Handler>();
_immediateStaticHandler = _serviceProvider.GetRequiredService<StaticIhExample.Handler>();
_immediateSealedHandler = _serviceProvider.GetRequiredService<SealedIhExample.Handler>();
_handler = _serviceProvider.GetRequiredService<SomeHandlerClass>();
_request = new(Guid.NewGuid());

Expand All @@ -105,9 +120,15 @@ public void Cleanup()
}

[Benchmark]
public ValueTask<SomeResponse> SendRequest_ImmediateHandler()
public ValueTask<SomeResponse> SendRequest_ImmediateStaticHandler()
{
return _immediateStaticHandler!.HandleAsync(_request!, CancellationToken.None);
}

[Benchmark]
public ValueTask<SomeResponse> SendRequest_ImmediateSealedHandler()
{
return _immediateHandler!.HandleAsync(_request!, CancellationToken.None);
return _immediateSealedHandler!.HandleAsync(_request!, CancellationToken.None);
}

[Benchmark]
Expand Down
Loading