Skip to content

Commit

Permalink
Performance Benchmarks (#130)
Browse files Browse the repository at this point in the history
  • Loading branch information
pglombardo authored Mar 14, 2024
1 parent e03368f commit b647975
Show file tree
Hide file tree
Showing 13 changed files with 160 additions and 59 deletions.
1 change: 0 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,6 @@ csharp_style_unused_value_assignment_preference = discard_variable:suggestion
dotnet_diagnostic.IDE0059.severity = suggestion
dotnet_diagnostic.IDE0002.severity = none
dotnet_diagnostic.IDE0010.severity = none
dotnet_diagnostic.IDE0021.severity = none
dotnet_diagnostic.IDE0028.severity = none
dotnet_diagnostic.IDE0049.severity = none
dotnet_diagnostic.IDE0053.severity = none
Expand Down
1 change: 1 addition & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"version": "0.2.0",
"configurations": [

{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
Expand Down
86 changes: 50 additions & 36 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -1,41 +1,55 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/Tests/HiveMQtt.Test/HiveMQtt.Test.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/Tests/HiveMQtt.Test/HiveMQtt.Test.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/Tests/HiveMQtt.Test/HiveMQtt.Test.csproj"
],
"problemMatcher": "$msCompile"
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/Tests/HiveMQtt.Test/HiveMQtt.Test.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/Tests/HiveMQtt.Test/HiveMQtt.Test.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/Tests/HiveMQtt.Test/HiveMQtt.Test.csproj"
],
"problemMatcher": "$msCompile"
},
{
"label": "build ClientBenchmarkApp",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/Benchmarks/ClientBenchmarkApp/ClientBenchmarkApp.csproj"
],
"problemMatcher": "$msCompile",
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
}
71 changes: 71 additions & 0 deletions Benchmarks/ClientBenchmarkApp/ClientBenchmark.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
namespace ClientBenchmarkApp;

using System;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Engines;

using HiveMQtt.Client;
using HiveMQtt.Client.Options;
using HiveMQtt.MQTT5;
using HiveMQtt.MQTT5.ReasonCodes;
using HiveMQtt.MQTT5.Types;

[SimpleJob(RunStrategy.Monitoring, iterationCount: 10, id: "MonitoringJob")]
public class ClientBenchmarks : IDisposable
{
private readonly string smallPayload = new string(/*lang=json,strict*/ "{\"interference\": \"1029384\"}");

private HiveMQClient client;

[GlobalSetup]
public async Task SetupAsync()
{
var options = new HiveMQClientOptions
{
Host = "127.0.0.1",
Port = 1883,
};

this.client = new HiveMQClient(options);
Console.WriteLine($"Connecting to {options.Host} on port {options.Port}...");
await this.client.ConnectAsync().ConfigureAwait(false);

if (this.client.IsConnected())
{
Console.WriteLine("HiveMQ client connected.");
}
else
{
Console.WriteLine("Client failed to connect!");
}
}

[GlobalCleanup]
public async Task CleanUpAsync()
{
Console.WriteLine("Disconnecting from HiveMQ...");
await this.client.DisconnectAsync().ConfigureAwait(false);
}

[Benchmark(Description = "Publish a QoS 0 messages to the broker.")]
public async Task PublishQoS0MessageAsync()
{
await this.client.PublishAsync("benchmarks/PublishQoS0Messages", this.smallPayload).ConfigureAwait(false);
}

[Benchmark(Description = "Publish a QoS 1 messages to the broker.")]
public async Task PublishQoS1MessageAsync()
{
await this.client.PublishAsync("benchmarks/PublishQoS1Messages", this.smallPayload, QualityOfService.AtLeastOnceDelivery).ConfigureAwait(false);
}

[Benchmark(Description = "Publish a QoS 2 messages to the broker.")]
public async Task PublishQoS2MessageAsync()
{
await this.client.PublishAsync("benchmarks/PublishQoS1Messages", this.smallPayload, QualityOfService.ExactlyOnceDelivery).ConfigureAwait(false);
}

public void Dispose() => GC.SuppressFinalize(this);
}
15 changes: 15 additions & 0 deletions Benchmarks/ClientBenchmarkApp/ClientBenchmarkApp.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.12" />
<ProjectReference Include="..\..\Source\HiveMQtt\HiveMQtt.csproj" />
</ItemGroup>

</Project>
11 changes: 11 additions & 0 deletions Benchmarks/ClientBenchmarkApp/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace ClientBenchmarkApp;

using System;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;

public class Program
{
public static void Main(string[] args)
=> BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
}
5 changes: 5 additions & 0 deletions Benchmarks/ClientBenchmarkApp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Benchmarks

The benchmarks are built with [BenchmarkDotNet](https://benchmarkdotnet.org) and can be run with:

`dotnet run ClientBenchmarkApp.csproj -c Release`
7 changes: 2 additions & 5 deletions Source/HiveMQtt/Client/HiveMQClientTrafficProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,14 @@ private Task<bool> TrafficOutflowProcessorAsync(CancellationToken cancellationTo
{
var stopWatch = new Stopwatch();
var keepAlivePeriod = this.Options.KeepAlive / 2;
TimeSpan elapsed;

stopWatch.Start();

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

while (this.connectState != ConnectState.Disconnected)
{
elapsed = stopWatch.Elapsed;

if (elapsed > TimeSpan.FromSeconds(keepAlivePeriod))
if (stopWatch.Elapsed > TimeSpan.FromSeconds(keepAlivePeriod))
{
// Send PingReq
Logger.Trace("--> PingReq");
Expand All @@ -80,7 +77,7 @@ private Task<bool> TrafficOutflowProcessorAsync(CancellationToken cancellationTo

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

// Batch load up to 20 queued packets
// Batch load up to 50 queued packets
List<ControlPacket> packetsToSend = new();
while (this.sendQueue.TryDequeue(out var p))
{
Expand Down
2 changes: 1 addition & 1 deletion Source/HiveMQtt/Client/HiveMQClientUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public static bool MatchTopic(string pattern, string candidate)

if (pattern == "+")
{
// A subscription to “+” will not receive any messages published to a topic containing a $
// A subscription to “+” will not receive any messages published to a topic beginning with a $ or /
if (candidate.StartsWith("$", System.StringComparison.CurrentCulture) ||
candidate.StartsWith("/", System.StringComparison.CurrentCulture))
{
Expand Down
5 changes: 1 addition & 4 deletions Source/HiveMQtt/Client/PublishMessageBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@ public class PublishMessageBuilder
/// </summary>
private readonly MQTT5PublishMessage message;

public PublishMessageBuilder()
{
this.message = new MQTT5PublishMessage();
}
public PublishMessageBuilder() => this.message = new MQTT5PublishMessage();

/// <summary>
/// Sets the payload of the publish message.
Expand Down
5 changes: 1 addition & 4 deletions Source/HiveMQtt/Client/Results/UnsubscribeResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,7 @@ namespace HiveMQtt.Client.Results;

public class UnsubscribeResult
{
public UnsubscribeResult()
{
this.Subscriptions = new List<Subscription>();
}
public UnsubscribeResult() => this.Subscriptions = new List<Subscription>();

public List<Subscription> Subscriptions { get; set; }
}
5 changes: 1 addition & 4 deletions Source/HiveMQtt/Client/SubscribeOptionsBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@ public class SubscribeOptionsBuilder
{
private readonly SubscribeOptions options;

public SubscribeOptionsBuilder()
{
this.options = new SubscribeOptions();
}
public SubscribeOptionsBuilder() => this.options = new SubscribeOptions();

/// <summary>
/// Adds a subscription to the list of subscriptions to be sent in the subscribe call.
Expand Down
5 changes: 1 addition & 4 deletions Source/HiveMQtt/Client/UnsubscribeOptionsBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@ public class UnsubscribeOptionsBuilder
{
private readonly UnsubscribeOptions options;

public UnsubscribeOptionsBuilder()
{
this.options = new UnsubscribeOptions();
}
public UnsubscribeOptionsBuilder() => this.options = new UnsubscribeOptions();

/// <summary>
/// Adds a single subscription to the UnsubscribeOption.
Expand Down

0 comments on commit b647975

Please sign in to comment.