Skip to content

Commit 8a5fff7

Browse files
committed
Evolve benchmark
Signed-off-by: Tomasz Maruszak <maruszaktomasz@gmail.com>
1 parent 0abaafa commit 8a5fff7

File tree

11 files changed

+122
-60
lines changed

11 files changed

+122
-60
lines changed

src/Host.Plugin.Properties.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<Import Project="Common.NuGet.Properties.xml" />
55

66
<PropertyGroup>
7-
<Version>3.0.0-rc902</Version>
7+
<Version>3.0.0-rc903</Version>
88
</PropertyGroup>
99

1010
</Project>

src/SlimMessageBus.Host.Configuration/SlimMessageBus.Host.Configuration.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<Description>Core configuration interfaces of SlimMessageBus</Description>
77
<PackageTags>SlimMessageBus</PackageTags>
88
<RootNamespace>SlimMessageBus.Host</RootNamespace>
9-
<Version>3.0.0-rc901</Version>
9+
<Version>3.0.0-rc903</Version>
1010
</PropertyGroup>
1111

1212
<ItemGroup>

src/SlimMessageBus.Host.Interceptor/SlimMessageBus.Host.Interceptor.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<Import Project="../Common.NuGet.Properties.xml" />
44

55
<PropertyGroup>
6-
<Version>3.0.0-rc901</Version>
6+
<Version>3.0.0-rc903</Version>
77
<Description>Core interceptor interfaces of SlimMessageBus</Description>
88
<PackageTags>SlimMessageBus</PackageTags>
99
</PropertyGroup>

src/SlimMessageBus.Host.Memory/Consumers/MessageProcessorQueue.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
namespace SlimMessageBus.Host.Memory;
22

3-
public class MessageProcessorQueue(IMessageProcessor<object> messageProcessor, ILogger<MessageProcessorQueue> logger, CancellationToken cancellationToken) : AbstractMessageProcessorQueue(messageProcessor, logger)
3+
public class MessageProcessorQueue(IMessageProcessor<object> messageProcessor,
4+
ILogger<MessageProcessorQueue> logger,
5+
CancellationToken cancellationToken)
6+
: AbstractMessageProcessorQueue(messageProcessor, logger)
47
{
58
private readonly object _prevTaskLock = new();
69
private Task _prevTask = null;

src/SlimMessageBus.Host.Serialization.Avro/AvroMessageSerializer.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ public AvroMessageSerializer(ILoggerFactory loggerFactory = null)
5252
var mf = new ReflectionMessageCreationStrategy(loggerFactory.CreateLogger<ReflectionMessageCreationStrategy>());
5353
var ml = new ReflectionSchemaLookupStrategy(loggerFactory.CreateLogger<ReflectionSchemaLookupStrategy>());
5454

55-
MessageFactory = (Type type) => mf.Create(type);
56-
WriteSchemaLookup = (Type type) => ml.Lookup(type);
55+
MessageFactory = mf.Create;
56+
WriteSchemaLookup = ml.Lookup;
5757
ReadSchemaLookup = WriteSchemaLookup;
5858
}
5959

@@ -73,7 +73,7 @@ public AvroMessageSerializer(ILoggerFactory loggerFactory, IMessageCreationStrat
7373
public object Deserialize(Type t, byte[] payload)
7474
{
7575
using var ms = ReadMemoryStreamFactory(payload);
76-
76+
7777
var dec = new BinaryDecoder(ms);
7878

7979
var message = MessageFactory(t);
@@ -84,7 +84,7 @@ public object Deserialize(Type t, byte[] payload)
8484
var writerSchema = WriteSchemaLookup(t);
8585
AssertSchemaNotNull(t, writerSchema, true);
8686

87-
_logger.LogDebug("Type {0} writer schema: {1}, reader schema: {2}", t, writerSchema, readerSchema);
87+
_logger.LogDebug("Type {Type} writer schema: {WriterSchema}, reader schema: {ReaderSchema}", t, writerSchema, readerSchema);
8888

8989
var reader = new SpecificDefaultReader(writerSchema, readerSchema);
9090
reader.Read(message, dec);
@@ -108,7 +108,7 @@ public byte[] Serialize(Type t, object message)
108108
var writerSchema = WriteSchemaLookup(t);
109109
AssertSchemaNotNull(t, writerSchema, true);
110110

111-
_logger.LogDebug("Type {0} writer schema: {1}", t, writerSchema);
111+
_logger.LogDebug("Type {Type} writer schema: {WriterSchema}", t, writerSchema);
112112

113113
var writer = new SpecificDefaultWriter(writerSchema); // Schema comes from pre-compiled, code-gen phase
114114
writer.Write(message, enc);

src/SlimMessageBus.Host.Serialization/SlimMessageBus.Host.Serialization.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<Import Project="../Common.NuGet.Properties.xml" />
44

55
<PropertyGroup>
6-
<Version>3.0.0-rc901</Version>
6+
<Version>3.0.0-rc903</Version>
77
<Description>Core serialization interfaces of SlimMessageBus</Description>
88
<PackageTags>SlimMessageBus</PackageTags>
99
</PropertyGroup>

src/SlimMessageBus/SlimMessageBus.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<Import Project="../Common.NuGet.Properties.xml" />
44

55
<PropertyGroup>
6-
<Version>3.0.0-rc902</Version>
6+
<Version>3.0.0-rc903</Version>
77
<Description>
88
This library provides a lightweight, easy-to-use message bus interface for .NET, offering a simplified facade for working with messaging brokers.
99
It supports multiple transport providers for popular messaging systems, as well as in-memory (in-process) messaging for efficient local communication.
Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,41 @@
11
namespace SlimMessageBus.Host.Memory.Benchmark;
22

3+
using System.Reflection;
4+
35
using Microsoft.Extensions.DependencyInjection;
6+
using Microsoft.Extensions.Logging;
7+
using Microsoft.Extensions.Logging.Abstractions;
48

59
using SlimMessageBus.Host;
610

7-
using System.Reflection;
8-
911
public abstract class AbstractMemoryBenchmark : IDisposable
1012
{
11-
protected ServiceProvider svp;
12-
protected readonly IMessageBus bus;
13+
private Lazy<ServiceProvider> _serviceProvider;
14+
15+
protected IServiceProvider ServiceProvider => _serviceProvider.Value;
16+
17+
protected bool PerMessageScopeEnabled { get; set; }
18+
19+
protected IMessageBus Bus => ServiceProvider.GetRequiredService<IMessageBus>();
1320

1421
protected AbstractMemoryBenchmark()
1522
{
16-
var services = new ServiceCollection();
17-
18-
services.AddSlimMessageBus(mbb => mbb.WithProviderMemory().AutoDeclareFrom(Assembly.GetExecutingAssembly()));
23+
_serviceProvider = new Lazy<ServiceProvider>(() =>
24+
{
25+
var services = new ServiceCollection();
1926

20-
services.AddSingleton<TestResult>();
21-
services.AddTransient<SomeRequestHandler>();
22-
Setup(services);
27+
services.AddSlimMessageBus(mbb => mbb
28+
.WithProviderMemory()
29+
.AutoDeclareFrom(Assembly.GetExecutingAssembly())
30+
.PerMessageScopeEnabled(PerMessageScopeEnabled));
2331

24-
svp = services.BuildServiceProvider();
32+
services.AddSingleton<ILoggerFactory>(NullLoggerFactory.Instance);
33+
services.AddSingleton<TestResult>();
34+
services.AddTransient<SomeRequestHandler>();
35+
Setup(services);
2536

26-
bus = svp.GetRequiredService<IMessageBus>();
37+
return services.BuildServiceProvider();
38+
});
2739
}
2840

2941
protected virtual void Setup(ServiceCollection services)
@@ -32,10 +44,10 @@ protected virtual void Setup(ServiceCollection services)
3244

3345
public void Dispose()
3446
{
35-
if (svp != null)
47+
if (_serviceProvider.Value != null)
3648
{
37-
svp.Dispose();
38-
svp = null;
49+
_serviceProvider.Value.Dispose();
50+
_serviceProvider = null;
3951
}
4052
}
4153
}

src/Tests/SlimMessageBus.Host.Memory.Benchmark/PubSubBenchmark.cs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,21 @@
88

99
public abstract class PubSubBaseBenchmark : AbstractMemoryBenchmark
1010
{
11-
private readonly TestResult testResult;
12-
13-
public PubSubBaseBenchmark()
14-
{
15-
testResult = svp.GetRequiredService<TestResult>();
16-
}
17-
1811
protected override void Setup(ServiceCollection services)
1912
{
2013
services.AddSingleton<TestResult>();
2114
services.AddTransient<SomeEventConsumer>();
2215
}
2316

24-
protected async Task RunTest(int messageCount)
17+
protected async Task RunTest(int messageCount, bool createMessageScope)
2518
{
19+
PerMessageScopeEnabled = createMessageScope;
20+
var bus = Bus;
2621
var publishTasks = Enumerable.Range(0, messageCount).Select(x => bus.Publish(new SomeEvent(DateTimeOffset.Now, x)));
2722

2823
await Task.WhenAll(publishTasks);
2924

25+
var testResult = ServiceProvider.GetRequiredService<TestResult>();
3026
while (testResult.ArrivedCount < messageCount)
3127
{
3228
await Task.Yield();
@@ -38,8 +34,9 @@ protected async Task RunTest(int messageCount)
3834
public class PubSubBenchmark : PubSubBaseBenchmark
3935
{
4036
[Benchmark]
41-
[Arguments(1000000)]
42-
public Task PubSub(int messageCount) => RunTest(messageCount);
37+
[Arguments(1000000, true)]
38+
[Arguments(1000000, false)]
39+
public Task PubSub(int messageCount, bool createMessageScope) => RunTest(messageCount, createMessageScope);
4340
}
4441

4542
[MemoryDiagnoser]
@@ -53,8 +50,9 @@ protected override void Setup(ServiceCollection services)
5350
}
5451

5552
[Benchmark]
56-
[Arguments(1000000)]
57-
public Task PubSubWithProducerInterceptor(int messageCount) => RunTest(messageCount);
53+
[Arguments(1000000, true)]
54+
[Arguments(1000000, false)]
55+
public Task PubSubWithProducerInterceptor(int messageCount, bool createMessageScope) => RunTest(messageCount, createMessageScope);
5856
}
5957

6058
[MemoryDiagnoser]
@@ -68,8 +66,9 @@ protected override void Setup(ServiceCollection services)
6866
}
6967

7068
[Benchmark]
71-
[Arguments(1000000)]
72-
public Task PubSubWithPublishInterceptor(int messageCount) => RunTest(messageCount);
69+
[Arguments(1000000, true)]
70+
[Arguments(1000000, false)]
71+
public Task PubSubWithPublishInterceptor(int messageCount, bool createMessageScope) => RunTest(messageCount, createMessageScope);
7372
}
7473

7574
[MemoryDiagnoser]
@@ -83,8 +82,9 @@ protected override void Setup(ServiceCollection services)
8382
}
8483

8584
[Benchmark]
86-
[Arguments(1000000)]
87-
public Task PubSubWithConsumerInterceptor(int messageCount) => RunTest(messageCount);
85+
[Arguments(1000000, true)]
86+
[Arguments(1000000, false)]
87+
public Task PubSubWithConsumerInterceptor(int messageCount, bool createMessageScope) => RunTest(messageCount, createMessageScope);
8888
}
8989

9090
public record SomeEvent(DateTimeOffset Timestamp, long Id);
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
Sample Benchmark results
2+
3+
```
4+
// * Summary *
5+
6+
BenchmarkDotNet v0.14.0, Windows 11 (10.0.26100.2454)
7+
12th Gen Intel Core i7-1260P, 1 CPU, 16 logical and 12 physical cores
8+
.NET SDK 9.0.100
9+
[Host] : .NET 8.0.11 (8.0.1124.51707), X64 RyuJIT AVX2
10+
Job-WFUQPN : .NET 8.0.11 (8.0.1124.51707), X64 RyuJIT AVX2
11+
12+
MaxIterationCount=30 MaxWarmupIterationCount=10
13+
```
14+
15+
| Type | Method | messageCount | createMessageScope | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated |
16+
| -------------------------------------- | ----------------------------- | ------------ | ------------------ | -------: | -------: | -------: | ----------: | --------: | --------: | --------: |
17+
| PubSubBenchmark | PubSub | 1000000 | False | 730.6 ms | 14.58 ms | 17.36 ms | 119000.0000 | 3000.0000 | 3000.0000 | 1.04 GB |
18+
| PubSubWithConsumerInterceptorBenchmark | PubSubWithConsumerInterceptor | 1000000 | False | 810.5 ms | 16.16 ms | 16.59 ms | 146000.0000 | 3000.0000 | 3000.0000 | 1.28 GB |
19+
| PubSubWithProducerInterceptorBenchmark | PubSubWithProducerInterceptor | 1000000 | False | 823.5 ms | 7.74 ms | 6.86 ms | 156000.0000 | 3000.0000 | 3000.0000 | 1.37 GB |
20+
| PubSubWithPublishInterceptorBenchmark | PubSubWithPublishInterceptor | 1000000 | False | 831.8 ms | 9.43 ms | 7.87 ms | 156000.0000 | 3000.0000 | 3000.0000 | 1.37 GB |
21+
| PubSubBenchmark | PubSub | 1000000 | True | 794.8 ms | 5.44 ms | 4.54 ms | 137000.0000 | 3000.0000 | 3000.0000 | 1.2 GB |
22+
| PubSubWithConsumerInterceptorBenchmark | PubSubWithConsumerInterceptor | 1000000 | True | 900.9 ms | 11.65 ms | 10.32 ms | 164000.0000 | 3000.0000 | 3000.0000 | 1.44 GB |
23+
| PubSubWithProducerInterceptorBenchmark | PubSubWithProducerInterceptor | 1000000 | True | 934.5 ms | 14.15 ms | 13.24 ms | 174000.0000 | 3000.0000 | 3000.0000 | 1.53 GB |
24+
| PubSubWithPublishInterceptorBenchmark | PubSubWithPublishInterceptor | 1000000 | True | 930.6 ms | 14.29 ms | 13.37 ms | 174000.0000 | 3000.0000 | 3000.0000 | 1.53 GB |
25+
26+
```
27+
// * Hints *
28+
29+
Outliers
30+
PubSubWithProducerInterceptorBenchmark.PubSubWithProducerInterceptor: MaxIterationCount=30, MaxWarmupIterationCount=10 -> 1 outlier was removed (840.20 ms)
31+
PubSubWithPublishInterceptorBenchmark.PubSubWithPublishInterceptor: MaxIterationCount=30, MaxWarmupIterationCount=10 -> 2 outliers were removed (862.16 ms, 863.90 ms)
32+
PubSubBenchmark.PubSub: MaxIterationCount=30, MaxWarmupIterationCount=10 -> 2 outliers were removed (810.49 ms, 823.65 ms)
33+
PubSubWithConsumerInterceptorBenchmark.PubSubWithConsumerInterceptor: MaxIterationCount=30, MaxWarmupIterationCount=10 -> 1 outlier was removed (947.16 ms)
34+
35+
// * Legends *
36+
messageCount : Value of the 'messageCount' parameter
37+
createMessageScope : Value of the 'createMessageScope' parameter
38+
Mean : Arithmetic mean of all measurements
39+
Error : Half of 99.9% confidence interval
40+
StdDev : Standard deviation of all measurements
41+
Gen0 : GC Generation 0 collects per 1000 operations
42+
Gen1 : GC Generation 1 collects per 1000 operations
43+
Gen2 : GC Generation 2 collects per 1000 operations
44+
Allocated : Allocated memory per single operation (managed only, inclusive, 1KB = 1024B)
45+
1 ms : 1 Millisecond (0.001 sec)
46+
```

0 commit comments

Comments
 (0)