-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathCqsBenchmarks.cs
More file actions
78 lines (59 loc) · 3.28 KB
/
CqsBenchmarks.cs
File metadata and controls
78 lines (59 loc) · 3.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Order;
using softaware.Cqs.Benchmarks.Contracts.Commands;
using softaware.Cqs.Benchmarks.Contracts.Queries;
namespace softaware.Cqs.Benchmarks;
[MemoryDiagnoser]
[Orderer(SummaryOrderPolicy.FastestToSlowest)]
public class CqsBenchmarks
{
private IRequestProcessor runtimeProcessor = null!;
private IRequestProcessor generatedProcessor = null!;
private IServiceProvider runtimeServiceProvider = null!;
private IServiceProvider generatedServiceProvider = null!;
[GlobalSetup]
public void Setup()
{
// Setup runtime (Scrutor-based) approach
this.runtimeServiceProvider = RuntimeSetup.CreateServiceProvider();
this.runtimeProcessor = this.runtimeServiceProvider.GetRequiredService<IRequestProcessor>();
// Setup compile-time (source-generated) approach
this.generatedServiceProvider = SourceGeneratedSetup.CreateServiceProvider();
this.generatedProcessor = this.generatedServiceProvider.GetRequiredService<IRequestProcessor>();
}
// --- Startup benchmarks ---
[Benchmark(Description = "Runtime: DI Container Build")]
public static IServiceProvider Runtime_ContainerBuild()
=> RuntimeSetup.CreateServiceProvider();
[Benchmark(Description = "Generated: DI Container Build")]
public static IServiceProvider Generated_ContainerBuild()
=> SourceGeneratedSetup.CreateServiceProvider();
// --- Command execution benchmarks ---
[Benchmark(Description = "Runtime: Execute SimpleCommand")]
public async Task Runtime_SimpleCommand()
=> await this.runtimeProcessor.HandleAsync(new SimpleCommand { Value = 1 }, default);
[Benchmark(Description = "Generated: Execute SimpleCommand")]
public async Task Generated_SimpleCommand()
=> await this.generatedProcessor.HandleAsync(new SimpleCommand { Value = 1 }, default);
// --- Query execution benchmarks ---
[Benchmark(Description = "Runtime: Execute GetSquare")]
public async Task<int> Runtime_GetSquare()
=> await this.runtimeProcessor.HandleAsync(new GetSquare { Value = 5 }, default);
[Benchmark(Description = "Generated: Execute GetSquare")]
public async Task<int> Generated_GetSquare()
=> await this.generatedProcessor.HandleAsync(new GetSquare { Value = 5 }, default);
// --- Access-checked command (multiple decorator constraints) ---
[Benchmark(Description = "Runtime: Execute AccessCheckedCommand")]
public async Task Runtime_AccessCheckedCommand()
=> await this.runtimeProcessor.HandleAsync(new AccessCheckedCommand(), default);
[Benchmark(Description = "Generated: Execute AccessCheckedCommand")]
public async Task Generated_AccessCheckedCommand()
=> await this.generatedProcessor.HandleAsync(new AccessCheckedCommand(), default);
// --- Query with caching + logging decorators ---
[Benchmark(Description = "Runtime: Execute GetGreeting")]
public async Task<string> Runtime_GetGreeting()
=> await this.runtimeProcessor.HandleAsync(new GetGreeting { Name = "World" }, default);
[Benchmark(Description = "Generated: Execute GetGreeting")]
public async Task<string> Generated_GetGreeting()
=> await this.generatedProcessor.HandleAsync(new GetGreeting { Name = "World" }, default);
}