Skip to content

Commit b647975

Browse files
authored
Performance Benchmarks (#130)
1 parent e03368f commit b647975

13 files changed

+160
-59
lines changed

.editorconfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,6 @@ csharp_style_unused_value_assignment_preference = discard_variable:suggestion
188188
dotnet_diagnostic.IDE0059.severity = suggestion
189189
dotnet_diagnostic.IDE0002.severity = none
190190
dotnet_diagnostic.IDE0010.severity = none
191-
dotnet_diagnostic.IDE0021.severity = none
192191
dotnet_diagnostic.IDE0028.severity = none
193192
dotnet_diagnostic.IDE0049.severity = none
194193
dotnet_diagnostic.IDE0053.severity = none

.vscode/launch.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"version": "0.2.0",
33
"configurations": [
4+
45
{
56
// Use IntelliSense to find out which attributes exist for C# debugging
67
// Use hover for the description of the existing attributes

.vscode/tasks.json

Lines changed: 50 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,55 @@
11
{
22
"version": "2.0.0",
33
"tasks": [
4-
{
5-
"label": "build",
6-
"command": "dotnet",
7-
"type": "process",
8-
"args": [
9-
"build",
10-
"${workspaceFolder}/Tests/HiveMQtt.Test/HiveMQtt.Test.csproj",
11-
"/property:GenerateFullPaths=true",
12-
"/consoleloggerparameters:NoSummary"
13-
],
14-
"problemMatcher": "$msCompile"
15-
},
16-
{
17-
"label": "publish",
18-
"command": "dotnet",
19-
"type": "process",
20-
"args": [
21-
"publish",
22-
"${workspaceFolder}/Tests/HiveMQtt.Test/HiveMQtt.Test.csproj",
23-
"/property:GenerateFullPaths=true",
24-
"/consoleloggerparameters:NoSummary"
25-
],
26-
"problemMatcher": "$msCompile"
27-
},
28-
{
29-
"label": "watch",
30-
"command": "dotnet",
31-
"type": "process",
32-
"args": [
33-
"watch",
34-
"run",
35-
"--project",
36-
"${workspaceFolder}/Tests/HiveMQtt.Test/HiveMQtt.Test.csproj"
37-
],
38-
"problemMatcher": "$msCompile"
4+
{
5+
"label": "build",
6+
"command": "dotnet",
7+
"type": "process",
8+
"args": [
9+
"build",
10+
"${workspaceFolder}/Tests/HiveMQtt.Test/HiveMQtt.Test.csproj",
11+
"/property:GenerateFullPaths=true",
12+
"/consoleloggerparameters:NoSummary"
13+
],
14+
"problemMatcher": "$msCompile"
15+
},
16+
{
17+
"label": "publish",
18+
"command": "dotnet",
19+
"type": "process",
20+
"args": [
21+
"publish",
22+
"${workspaceFolder}/Tests/HiveMQtt.Test/HiveMQtt.Test.csproj",
23+
"/property:GenerateFullPaths=true",
24+
"/consoleloggerparameters:NoSummary"
25+
],
26+
"problemMatcher": "$msCompile"
27+
},
28+
{
29+
"label": "watch",
30+
"command": "dotnet",
31+
"type": "process",
32+
"args": [
33+
"watch",
34+
"run",
35+
"--project",
36+
"${workspaceFolder}/Tests/HiveMQtt.Test/HiveMQtt.Test.csproj"
37+
],
38+
"problemMatcher": "$msCompile"
39+
},
40+
{
41+
"label": "build ClientBenchmarkApp",
42+
"command": "dotnet",
43+
"type": "process",
44+
"args": [
45+
"build",
46+
"${workspaceFolder}/Benchmarks/ClientBenchmarkApp/ClientBenchmarkApp.csproj"
47+
],
48+
"problemMatcher": "$msCompile",
49+
"group": {
50+
"kind": "build",
51+
"isDefault": true
3952
}
53+
}
4054
]
41-
}
55+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
namespace ClientBenchmarkApp;
2+
3+
using System;
4+
using BenchmarkDotNet.Attributes;
5+
using BenchmarkDotNet.Running;
6+
using BenchmarkDotNet.Jobs;
7+
using BenchmarkDotNet.Engines;
8+
9+
using HiveMQtt.Client;
10+
using HiveMQtt.Client.Options;
11+
using HiveMQtt.MQTT5;
12+
using HiveMQtt.MQTT5.ReasonCodes;
13+
using HiveMQtt.MQTT5.Types;
14+
15+
[SimpleJob(RunStrategy.Monitoring, iterationCount: 10, id: "MonitoringJob")]
16+
public class ClientBenchmarks : IDisposable
17+
{
18+
private readonly string smallPayload = new string(/*lang=json,strict*/ "{\"interference\": \"1029384\"}");
19+
20+
private HiveMQClient client;
21+
22+
[GlobalSetup]
23+
public async Task SetupAsync()
24+
{
25+
var options = new HiveMQClientOptions
26+
{
27+
Host = "127.0.0.1",
28+
Port = 1883,
29+
};
30+
31+
this.client = new HiveMQClient(options);
32+
Console.WriteLine($"Connecting to {options.Host} on port {options.Port}...");
33+
await this.client.ConnectAsync().ConfigureAwait(false);
34+
35+
if (this.client.IsConnected())
36+
{
37+
Console.WriteLine("HiveMQ client connected.");
38+
}
39+
else
40+
{
41+
Console.WriteLine("Client failed to connect!");
42+
}
43+
}
44+
45+
[GlobalCleanup]
46+
public async Task CleanUpAsync()
47+
{
48+
Console.WriteLine("Disconnecting from HiveMQ...");
49+
await this.client.DisconnectAsync().ConfigureAwait(false);
50+
}
51+
52+
[Benchmark(Description = "Publish a QoS 0 messages to the broker.")]
53+
public async Task PublishQoS0MessageAsync()
54+
{
55+
await this.client.PublishAsync("benchmarks/PublishQoS0Messages", this.smallPayload).ConfigureAwait(false);
56+
}
57+
58+
[Benchmark(Description = "Publish a QoS 1 messages to the broker.")]
59+
public async Task PublishQoS1MessageAsync()
60+
{
61+
await this.client.PublishAsync("benchmarks/PublishQoS1Messages", this.smallPayload, QualityOfService.AtLeastOnceDelivery).ConfigureAwait(false);
62+
}
63+
64+
[Benchmark(Description = "Publish a QoS 2 messages to the broker.")]
65+
public async Task PublishQoS2MessageAsync()
66+
{
67+
await this.client.PublishAsync("benchmarks/PublishQoS1Messages", this.smallPayload, QualityOfService.ExactlyOnceDelivery).ConfigureAwait(false);
68+
}
69+
70+
public void Dispose() => GC.SuppressFinalize(this);
71+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net6.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="BenchmarkDotNet" Version="0.13.12" />
12+
<ProjectReference Include="..\..\Source\HiveMQtt\HiveMQtt.csproj" />
13+
</ItemGroup>
14+
15+
</Project>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace ClientBenchmarkApp;
2+
3+
using System;
4+
using BenchmarkDotNet.Attributes;
5+
using BenchmarkDotNet.Running;
6+
7+
public class Program
8+
{
9+
public static void Main(string[] args)
10+
=> BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
11+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Benchmarks
2+
3+
The benchmarks are built with [BenchmarkDotNet](https://benchmarkdotnet.org) and can be run with:
4+
5+
`dotnet run ClientBenchmarkApp.csproj -c Release`

Source/HiveMQtt/Client/HiveMQClientTrafficProcessor.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,14 @@ private Task<bool> TrafficOutflowProcessorAsync(CancellationToken cancellationTo
4646
{
4747
var stopWatch = new Stopwatch();
4848
var keepAlivePeriod = this.Options.KeepAlive / 2;
49-
TimeSpan elapsed;
5049

5150
stopWatch.Start();
5251

5352
Logger.Trace($"{Environment.CurrentManagedThreadId}: TrafficOutflowProcessor Starting...{this.connectState}");
5453

5554
while (this.connectState != ConnectState.Disconnected)
5655
{
57-
elapsed = stopWatch.Elapsed;
58-
59-
if (elapsed > TimeSpan.FromSeconds(keepAlivePeriod))
56+
if (stopWatch.Elapsed > TimeSpan.FromSeconds(keepAlivePeriod))
6057
{
6158
// Send PingReq
6259
Logger.Trace("--> PingReq");
@@ -80,7 +77,7 @@ private Task<bool> TrafficOutflowProcessorAsync(CancellationToken cancellationTo
8077

8178
Logger.Trace($"TrafficOutflowProcessor: {this.sendQueue.Count} packets waiting to be sent.");
8279

83-
// Batch load up to 20 queued packets
80+
// Batch load up to 50 queued packets
8481
List<ControlPacket> packetsToSend = new();
8582
while (this.sendQueue.TryDequeue(out var p))
8683
{

Source/HiveMQtt/Client/HiveMQClientUtil.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public static bool MatchTopic(string pattern, string candidate)
9999

100100
if (pattern == "+")
101101
{
102-
// A subscription to “+” will not receive any messages published to a topic containing a $
102+
// A subscription to “+” will not receive any messages published to a topic beginning with a $ or /
103103
if (candidate.StartsWith("$", System.StringComparison.CurrentCulture) ||
104104
candidate.StartsWith("/", System.StringComparison.CurrentCulture))
105105
{

Source/HiveMQtt/Client/PublishMessageBuilder.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,7 @@ public class PublishMessageBuilder
2525
/// </summary>
2626
private readonly MQTT5PublishMessage message;
2727

28-
public PublishMessageBuilder()
29-
{
30-
this.message = new MQTT5PublishMessage();
31-
}
28+
public PublishMessageBuilder() => this.message = new MQTT5PublishMessage();
3229

3330
/// <summary>
3431
/// Sets the payload of the publish message.

Source/HiveMQtt/Client/Results/UnsubscribeResult.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@ namespace HiveMQtt.Client.Results;
1919

2020
public class UnsubscribeResult
2121
{
22-
public UnsubscribeResult()
23-
{
24-
this.Subscriptions = new List<Subscription>();
25-
}
22+
public UnsubscribeResult() => this.Subscriptions = new List<Subscription>();
2623

2724
public List<Subscription> Subscriptions { get; set; }
2825
}

Source/HiveMQtt/Client/SubscribeOptionsBuilder.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,7 @@ public class SubscribeOptionsBuilder
2323
{
2424
private readonly SubscribeOptions options;
2525

26-
public SubscribeOptionsBuilder()
27-
{
28-
this.options = new SubscribeOptions();
29-
}
26+
public SubscribeOptionsBuilder() => this.options = new SubscribeOptions();
3027

3128
/// <summary>
3229
/// Adds a subscription to the list of subscriptions to be sent in the subscribe call.

Source/HiveMQtt/Client/UnsubscribeOptionsBuilder.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,7 @@ public class UnsubscribeOptionsBuilder
2222
{
2323
private readonly UnsubscribeOptions options;
2424

25-
public UnsubscribeOptionsBuilder()
26-
{
27-
this.options = new UnsubscribeOptions();
28-
}
25+
public UnsubscribeOptionsBuilder() => this.options = new UnsubscribeOptions();
2926

3027
/// <summary>
3128
/// Adds a single subscription to the UnsubscribeOption.

0 commit comments

Comments
 (0)