mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-21 20:33:05 +08:00
Refactor benchmarks (#1601)
This commit is contained in:
@@ -1,3 +1,7 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
namespace MQTTnet.Benchmarks
|
namespace MQTTnet.Benchmarks
|
||||||
{
|
{
|
||||||
public abstract class BaseBenchmark
|
public abstract class BaseBenchmark
|
||||||
|
|||||||
@@ -2,54 +2,25 @@
|
|||||||
// The .NET Foundation licenses this file to you under the MIT license.
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
using BenchmarkDotNet.Attributes;
|
|
||||||
using MQTTnet.Adapter;
|
|
||||||
using MQTTnet.Internal;
|
|
||||||
using MQTTnet.Packets;
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using BenchmarkDotNet.Attributes;
|
||||||
|
using MQTTnet.Adapter;
|
||||||
using MQTTnet.Diagnostics;
|
using MQTTnet.Diagnostics;
|
||||||
using MQTTnet.Formatter;
|
using MQTTnet.Formatter;
|
||||||
|
using MQTTnet.Packets;
|
||||||
using MQTTnet.Tests.Mockups;
|
using MQTTnet.Tests.Mockups;
|
||||||
|
|
||||||
namespace MQTTnet.Benchmarks
|
namespace MQTTnet.Benchmarks
|
||||||
{
|
{
|
||||||
[MemoryDiagnoser]
|
[MemoryDiagnoser]
|
||||||
public sealed class ChannelAdapterBenchmark
|
public sealed class ChannelAdapterBenchmark : BaseBenchmark
|
||||||
{
|
{
|
||||||
MqttChannelAdapter _channelAdapter;
|
MqttChannelAdapter _channelAdapter;
|
||||||
int _iterations;
|
int _iterations;
|
||||||
MemoryStream _stream;
|
|
||||||
MqttPublishPacket _packet;
|
MqttPublishPacket _packet;
|
||||||
|
MemoryStream _stream;
|
||||||
[GlobalSetup]
|
|
||||||
public void Setup()
|
|
||||||
{
|
|
||||||
_packet = new MqttPublishPacket
|
|
||||||
{
|
|
||||||
Topic = "A"
|
|
||||||
};
|
|
||||||
|
|
||||||
var serializer = new MqttPacketFormatterAdapter(MqttProtocolVersion.V311, new MqttBufferWriter(4096, 65535));
|
|
||||||
|
|
||||||
var serializedPacket = Join(serializer.Encode(_packet).Join());
|
|
||||||
|
|
||||||
_iterations = 10000;
|
|
||||||
|
|
||||||
_stream = new MemoryStream(_iterations * serializedPacket.Length);
|
|
||||||
|
|
||||||
for (var i = 0; i < _iterations; i++)
|
|
||||||
{
|
|
||||||
_stream.Write(serializedPacket, 0, serializedPacket.Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
_stream.Position = 0;
|
|
||||||
|
|
||||||
var channel = new MemoryMqttChannel(_stream);
|
|
||||||
|
|
||||||
_channelAdapter = new MqttChannelAdapter(channel, serializer, null, new MqttNetEventLogger());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Benchmark]
|
[Benchmark]
|
||||||
public void Receive_10000_Messages()
|
public void Receive_10000_Messages()
|
||||||
@@ -77,6 +48,34 @@ namespace MQTTnet.Benchmarks
|
|||||||
_stream.Position = 0;
|
_stream.Position = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GlobalSetup]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_packet = new MqttPublishPacket
|
||||||
|
{
|
||||||
|
Topic = "A"
|
||||||
|
};
|
||||||
|
|
||||||
|
var serializer = new MqttPacketFormatterAdapter(MqttProtocolVersion.V311, new MqttBufferWriter(4096, 65535));
|
||||||
|
|
||||||
|
var serializedPacket = Join(serializer.Encode(_packet).Join());
|
||||||
|
|
||||||
|
_iterations = 10000;
|
||||||
|
|
||||||
|
_stream = new MemoryStream(_iterations * serializedPacket.Length);
|
||||||
|
|
||||||
|
for (var i = 0; i < _iterations; i++)
|
||||||
|
{
|
||||||
|
_stream.Write(serializedPacket, 0, serializedPacket.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
_stream.Position = 0;
|
||||||
|
|
||||||
|
var channel = new MemoryMqttChannel(_stream);
|
||||||
|
|
||||||
|
_channelAdapter = new MqttChannelAdapter(channel, serializer, null, new MqttNetEventLogger());
|
||||||
|
}
|
||||||
|
|
||||||
static byte[] Join(params ArraySegment<byte>[] chunks)
|
static byte[] Join(params ArraySegment<byte>[] chunks)
|
||||||
{
|
{
|
||||||
var buffer = new MemoryStream();
|
var buffer = new MemoryStream();
|
||||||
@@ -88,4 +87,4 @@ namespace MQTTnet.Benchmarks
|
|||||||
return buffer.ToArray();
|
return buffer.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
// Licensed to the .NET Foundation under one or more agreements.
|
|
||||||
// The .NET Foundation licenses this file to you under the MIT license.
|
|
||||||
// See the LICENSE file in the project root for more information.
|
|
||||||
|
|
||||||
using BenchmarkDotNet.Jobs;
|
|
||||||
using BenchmarkDotNet.Validators;
|
|
||||||
|
|
||||||
namespace MQTTnet.Benchmarks.Configurations
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// this options may be used to run benchmarks in debugmode and attach a performance profiler
|
|
||||||
/// https://benchmarkdotnet.org/Configs/Configs.htm
|
|
||||||
/// </summary>
|
|
||||||
public class AllowNonOptimized : BaseConfig
|
|
||||||
{
|
|
||||||
public AllowNonOptimized()
|
|
||||||
{
|
|
||||||
AddValidator(JitOptimizationsValidator.DontFailOnError); // ALLOW NON-OPTIMIZED DLLS
|
|
||||||
AddJob(Job.InProcess);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
// Licensed to the .NET Foundation under one or more agreements.
|
|
||||||
// The .NET Foundation licenses this file to you under the MIT license.
|
|
||||||
// See the LICENSE file in the project root for more information.
|
|
||||||
|
|
||||||
using BenchmarkDotNet.Configs;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace MQTTnet.Benchmarks.Configurations
|
|
||||||
{
|
|
||||||
public class BaseConfig : ManualConfig
|
|
||||||
{
|
|
||||||
public BaseConfig()
|
|
||||||
{
|
|
||||||
AddLogger(DefaultConfig.Instance.GetLoggers().ToArray()); // manual config has no loggers by default
|
|
||||||
AddExporter(DefaultConfig.Instance.GetExporters().ToArray()); // manual config has no exporters by default
|
|
||||||
AddColumnProvider(DefaultConfig.Instance.GetColumnProviders().ToArray()); // manual config has no columns by default
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
// Licensed to the .NET Foundation under one or more agreements.
|
|
||||||
// The .NET Foundation licenses this file to you under the MIT license.
|
|
||||||
// See the LICENSE file in the project root for more information.
|
|
||||||
|
|
||||||
using BenchmarkDotNet.Environments;
|
|
||||||
using BenchmarkDotNet.Jobs;
|
|
||||||
using BenchmarkDotNet.Toolchains.CsProj;
|
|
||||||
|
|
||||||
namespace MQTTnet.Benchmarks.Configurations
|
|
||||||
{
|
|
||||||
public class RuntimeCompareConfig : BaseConfig
|
|
||||||
{
|
|
||||||
public RuntimeCompareConfig()
|
|
||||||
{
|
|
||||||
AddJob(Job.Default.WithRuntime(ClrRuntime.Net48));
|
|
||||||
AddJob(Job.Default.WithRuntime(CoreRuntime.Core50).WithToolchain(CsProjCoreToolchain.NetCoreApp50));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -11,7 +11,7 @@ namespace MQTTnet.Benchmarks
|
|||||||
[SimpleJob(RuntimeMoniker.Net60)]
|
[SimpleJob(RuntimeMoniker.Net60)]
|
||||||
[RPlotExporter]
|
[RPlotExporter]
|
||||||
[MemoryDiagnoser]
|
[MemoryDiagnoser]
|
||||||
public class LoggerBenchmark
|
public class LoggerBenchmark : BaseBenchmark
|
||||||
{
|
{
|
||||||
MqttNetNullLogger _nullLogger;
|
MqttNetNullLogger _nullLogger;
|
||||||
MqttNetSourceLogger _sourceNullLogger;
|
MqttNetSourceLogger _sourceNullLogger;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<DebugType>Full</DebugType>
|
<DebugType>Full</DebugType>
|
||||||
<TargetFrameworks>net5.0;net6.0</TargetFrameworks>
|
<TargetFrameworks>net6.0</TargetFrameworks>
|
||||||
<LangVersion>7.2</LangVersion>
|
<LangVersion>7.2</LangVersion>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
<EnableNETAnalyzers>false</EnableNETAnalyzers>
|
<EnableNETAnalyzers>false</EnableNETAnalyzers>
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
using BenchmarkDotNet.Attributes;
|
using BenchmarkDotNet.Attributes;
|
||||||
using BenchmarkDotNet.Jobs;
|
|
||||||
using MQTTnet.Client;
|
using MQTTnet.Client;
|
||||||
using MQTTnet.Server;
|
using MQTTnet.Server;
|
||||||
using System;
|
using System;
|
||||||
@@ -8,14 +11,10 @@ using System.Linq;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
|
||||||
namespace MQTTnet.Benchmarks
|
namespace MQTTnet.Benchmarks
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Create a number of topics, publish, subscribe, and wait for response
|
|
||||||
/// </summary>
|
|
||||||
[MemoryDiagnoser]
|
[MemoryDiagnoser]
|
||||||
public class MessageDeliveryBenchmark
|
public class MessageDeliveryBenchmark : BaseBenchmark
|
||||||
{
|
{
|
||||||
List<MqttApplicationMessage> _topicPublishMessages;
|
List<MqttApplicationMessage> _topicPublishMessages;
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace MQTTnet.Benchmarks
|
|||||||
[SimpleJob(RuntimeMoniker.Net60)]
|
[SimpleJob(RuntimeMoniker.Net60)]
|
||||||
[RPlotExporter, RankColumn]
|
[RPlotExporter, RankColumn]
|
||||||
[MemoryDiagnoser]
|
[MemoryDiagnoser]
|
||||||
public class MessageProcessingBenchmark
|
public class MessageProcessingBenchmark : BaseBenchmark
|
||||||
{
|
{
|
||||||
MqttServer _mqttServer;
|
MqttServer _mqttServer;
|
||||||
IMqttClient _mqttClient;
|
IMqttClient _mqttClient;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace MQTTnet.Benchmarks
|
|||||||
{
|
{
|
||||||
[SimpleJob(RuntimeMoniker.Net60)]
|
[SimpleJob(RuntimeMoniker.Net60)]
|
||||||
[MemoryDiagnoser]
|
[MemoryDiagnoser]
|
||||||
public class MessageProcessingMqttConnectionContextBenchmark
|
public class MessageProcessingMqttConnectionContextBenchmark : BaseBenchmark
|
||||||
{
|
{
|
||||||
IWebHost _host;
|
IWebHost _host;
|
||||||
IMqttClient _mqttClient;
|
IMqttClient _mqttClient;
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using BenchmarkDotNet.Attributes;
|
using BenchmarkDotNet.Attributes;
|
||||||
using BenchmarkDotNet.Jobs;
|
using BenchmarkDotNet.Jobs;
|
||||||
using MQTTnet.AspNetCore;
|
|
||||||
using MQTTnet.Formatter;
|
using MQTTnet.Formatter;
|
||||||
using MQTTnet.Tests.Mockups;
|
using MQTTnet.Tests.Mockups;
|
||||||
|
|
||||||
@@ -9,7 +12,7 @@ namespace MQTTnet.Benchmarks
|
|||||||
{
|
{
|
||||||
[SimpleJob(RuntimeMoniker.Net60)]
|
[SimpleJob(RuntimeMoniker.Net60)]
|
||||||
[MemoryDiagnoser]
|
[MemoryDiagnoser]
|
||||||
public class MqttPacketReaderWriterBenchmark
|
public class MqttPacketReaderWriterBenchmark : BaseBenchmark
|
||||||
{
|
{
|
||||||
readonly byte[] _demoPayload = new byte[1024];
|
readonly byte[] _demoPayload = new byte[1024];
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace MQTTnet.Benchmarks
|
|||||||
{
|
{
|
||||||
[SimpleJob(RuntimeMoniker.Net60)]
|
[SimpleJob(RuntimeMoniker.Net60)]
|
||||||
[MemoryDiagnoser]
|
[MemoryDiagnoser]
|
||||||
public sealed class MqttTcpChannelBenchmark
|
public class MqttTcpChannelBenchmark : BaseBenchmark
|
||||||
{
|
{
|
||||||
MqttServer _mqttServer;
|
MqttServer _mqttServer;
|
||||||
IMqttChannel _serverChannel;
|
IMqttChannel _serverChannel;
|
||||||
|
|||||||
@@ -3,89 +3,140 @@
|
|||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using BenchmarkDotNet.Loggers;
|
||||||
using BenchmarkDotNet.Running;
|
using BenchmarkDotNet.Running;
|
||||||
using MQTTnet.Benchmarks.Configurations;
|
|
||||||
using MQTTnet.Diagnostics;
|
using MQTTnet.Diagnostics;
|
||||||
|
|
||||||
namespace MQTTnet.Benchmarks
|
namespace MQTTnet.Benchmarks
|
||||||
{
|
{
|
||||||
public static class Program
|
public static class Program
|
||||||
{
|
{
|
||||||
public static void Main(string[] args)
|
static int _selectedBenchmarkIndex;
|
||||||
{
|
static List<Type> _benchmarks;
|
||||||
Console.WriteLine($"MQTTnet - Benchmarks ({TargetFrameworkProvider.TargetFramework})");
|
|
||||||
Console.WriteLine("--------------------------------------------------------");
|
|
||||||
Console.WriteLine("1 = MessageProcessingBenchmark");
|
|
||||||
Console.WriteLine("2 = SerializerBenchmark");
|
|
||||||
Console.WriteLine("3 = LoggerBenchmark");
|
|
||||||
Console.WriteLine("4 = TopicFilterComparerBenchmark");
|
|
||||||
Console.WriteLine("5 = ChannelAdapterBenchmark");
|
|
||||||
Console.WriteLine("6 = MqttTcpChannelBenchmark");
|
|
||||||
Console.WriteLine("7 = TcpPipesBenchmark");
|
|
||||||
Console.WriteLine("8 = MessageProcessingMqttConnectionContextBenchmark");
|
|
||||||
Console.WriteLine("9 = ServerProcessingBenchmark");
|
|
||||||
Console.WriteLine("a = MqttPacketReaderWriterBenchmark");
|
|
||||||
Console.WriteLine("b = RoundtripBenchmark");
|
|
||||||
Console.WriteLine("c = SubscribeBenchmark");
|
|
||||||
Console.WriteLine("d = UnsubscribeBenchmark");
|
|
||||||
Console.WriteLine("e = MessageDeliveryBenchmark");
|
|
||||||
Console.WriteLine("f = AsyncLockBenchmark");
|
|
||||||
Console.WriteLine("g = MqttBufferReaderBenchmark");
|
|
||||||
|
|
||||||
var pressedKey = Console.ReadKey(true);
|
public static void Main(string[] arguments)
|
||||||
switch (pressedKey.KeyChar)
|
{
|
||||||
|
_benchmarks = CollectBenchmarks();
|
||||||
|
HandleArguments(arguments);
|
||||||
|
|
||||||
|
while (true)
|
||||||
{
|
{
|
||||||
case '1':
|
RenderMenu();
|
||||||
BenchmarkRunner.Run<MessageProcessingBenchmark>();
|
|
||||||
break;
|
var key = Console.ReadKey(true);
|
||||||
case '2':
|
|
||||||
BenchmarkRunner.Run<SerializerBenchmark>();
|
if (key.Key == ConsoleKey.DownArrow)
|
||||||
break;
|
{
|
||||||
case '3':
|
_selectedBenchmarkIndex++;
|
||||||
BenchmarkRunner.Run<LoggerBenchmark>();
|
if (_selectedBenchmarkIndex > _benchmarks.Count - 1)
|
||||||
break;
|
{
|
||||||
case '4':
|
_selectedBenchmarkIndex = 0;
|
||||||
BenchmarkRunner.Run<TopicFilterComparerBenchmark>();
|
}
|
||||||
break;
|
}
|
||||||
case '5':
|
else if (key.Key == ConsoleKey.UpArrow)
|
||||||
BenchmarkRunner.Run<ChannelAdapterBenchmark>();
|
{
|
||||||
break;
|
_selectedBenchmarkIndex--;
|
||||||
case '6':
|
if (_selectedBenchmarkIndex < 0)
|
||||||
BenchmarkRunner.Run<MqttTcpChannelBenchmark>();
|
{
|
||||||
break;
|
_selectedBenchmarkIndex = _benchmarks.Count - 1;
|
||||||
case '7':
|
}
|
||||||
BenchmarkRunner.Run<TcpPipesBenchmark>();
|
}
|
||||||
break;
|
else if (key.Key == ConsoleKey.Escape)
|
||||||
case '8':
|
{
|
||||||
BenchmarkRunner.Run<MessageProcessingMqttConnectionContextBenchmark>(new RuntimeCompareConfig());
|
Environment.Exit(0);
|
||||||
break;
|
}
|
||||||
case '9':
|
else if (key.Key == ConsoleKey.Enter)
|
||||||
BenchmarkRunner.Run<ServerProcessingBenchmark>();
|
{
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
BenchmarkRunner.Run(typeof(MqttPacketReaderWriterBenchmark));
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
BenchmarkRunner.Run<RoundtripProcessingBenchmark>();
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
BenchmarkRunner.Run<SubscribeBenchmark>();
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
BenchmarkRunner.Run<UnsubscribeBenchmark>();
|
|
||||||
break;
|
|
||||||
case 'e':
|
|
||||||
BenchmarkRunner.Run<MessageDeliveryBenchmark>();
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
BenchmarkRunner.Run<AsyncLockBenchmark>();
|
|
||||||
break;
|
|
||||||
case 'g':
|
|
||||||
BenchmarkRunner.Run<MqttBufferReaderBenchmark>();
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BenchmarkRunner.Run(_benchmarks[_selectedBenchmarkIndex]);
|
||||||
|
|
||||||
|
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||||
|
Console.WriteLine("Press any key to exit");
|
||||||
Console.ReadLine();
|
Console.ReadLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static List<Type> CollectBenchmarks()
|
||||||
|
{
|
||||||
|
var benchmarks = new List<Type>();
|
||||||
|
|
||||||
|
var types = typeof(Program).Assembly.GetExportedTypes();
|
||||||
|
foreach (var type in types)
|
||||||
|
{
|
||||||
|
if (typeof(BaseBenchmark).IsAssignableFrom(type))
|
||||||
|
{
|
||||||
|
if (type != typeof(BaseBenchmark))
|
||||||
|
{
|
||||||
|
benchmarks.Add(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return benchmarks.OrderBy(b => b.Name).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void HandleArguments(string[] arguments)
|
||||||
|
{
|
||||||
|
if (arguments.Length == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow for preselection to avoid developer frustration.
|
||||||
|
|
||||||
|
if (int.TryParse(arguments[0], out var benchmarkIndex))
|
||||||
|
{
|
||||||
|
_selectedBenchmarkIndex = benchmarkIndex;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_selectedBenchmarkIndex = _benchmarks.FindIndex(b => b.Name.Equals(arguments[0]));
|
||||||
|
|
||||||
|
if (_selectedBenchmarkIndex < 0)
|
||||||
|
{
|
||||||
|
_selectedBenchmarkIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_selectedBenchmarkIndex > _benchmarks.Count - 1)
|
||||||
|
{
|
||||||
|
_selectedBenchmarkIndex = _benchmarks.Count - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RenderMenu()
|
||||||
|
{
|
||||||
|
Console.Clear();
|
||||||
|
|
||||||
|
Console.WriteLine($"MQTTnet - Benchmarks ({TargetFrameworkProvider.TargetFramework})");
|
||||||
|
Console.WriteLine("-----------------------------------------------");
|
||||||
|
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||||
|
Console.WriteLine("Press arrow keys for benchmark selection");
|
||||||
|
Console.WriteLine("Press Enter for benchmark execution");
|
||||||
|
Console.WriteLine("Press Esc for exit");
|
||||||
|
Console.ForegroundColor = ConsoleColor.White;
|
||||||
|
Console.WriteLine();
|
||||||
|
|
||||||
|
for (var index = 0; index < _benchmarks.Count; index++)
|
||||||
|
{
|
||||||
|
var benchmark = _benchmarks[index];
|
||||||
|
|
||||||
|
if (_selectedBenchmarkIndex == index)
|
||||||
|
{
|
||||||
|
Console.Write("-> ");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.Write(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine(benchmark.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,7 @@ namespace MQTTnet.Benchmarks
|
|||||||
[SimpleJob(RuntimeMoniker.Net60)]
|
[SimpleJob(RuntimeMoniker.Net60)]
|
||||||
[RPlotExporter, RankColumn]
|
[RPlotExporter, RankColumn]
|
||||||
[MemoryDiagnoser]
|
[MemoryDiagnoser]
|
||||||
public class RoundtripProcessingBenchmark
|
public class RoundtripProcessingBenchmark : BaseBenchmark
|
||||||
{
|
{
|
||||||
[GlobalSetup]
|
[GlobalSetup]
|
||||||
public void GlobalSetup()
|
public void GlobalSetup()
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
using BenchmarkDotNet.Attributes;
|
using BenchmarkDotNet.Attributes;
|
||||||
using BenchmarkDotNet.Jobs;
|
using BenchmarkDotNet.Jobs;
|
||||||
using MQTTnet.Tests.Mockups;
|
using MQTTnet.Tests.Mockups;
|
||||||
@@ -8,7 +12,7 @@ namespace MQTTnet.Benchmarks
|
|||||||
[SimpleJob(RuntimeMoniker.Net60)]
|
[SimpleJob(RuntimeMoniker.Net60)]
|
||||||
[RPlotExporter, RankColumn]
|
[RPlotExporter, RankColumn]
|
||||||
[MemoryDiagnoser]
|
[MemoryDiagnoser]
|
||||||
public class ServerProcessingBenchmark
|
public class ServerProcessingBenchmark : BaseBenchmark
|
||||||
{
|
{
|
||||||
[GlobalSetup]
|
[GlobalSetup]
|
||||||
public void GlobalSetup()
|
public void GlobalSetup()
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
using BenchmarkDotNet.Attributes;
|
using BenchmarkDotNet.Attributes;
|
||||||
using BenchmarkDotNet.Jobs;
|
using BenchmarkDotNet.Jobs;
|
||||||
using MQTTnet.Client;
|
using MQTTnet.Client;
|
||||||
@@ -8,7 +12,7 @@ using System.Linq;
|
|||||||
namespace MQTTnet.Benchmarks
|
namespace MQTTnet.Benchmarks
|
||||||
{
|
{
|
||||||
[MemoryDiagnoser]
|
[MemoryDiagnoser]
|
||||||
public class SubscribeBenchmark
|
public class SubscribeBenchmark : BaseBenchmark
|
||||||
{
|
{
|
||||||
MqttServer _mqttServer;
|
MqttServer _mqttServer;
|
||||||
IMqttClient _mqttClient;
|
IMqttClient _mqttClient;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace MQTTnet.Benchmarks
|
|||||||
{
|
{
|
||||||
[SimpleJob(RuntimeMoniker.Net60)]
|
[SimpleJob(RuntimeMoniker.Net60)]
|
||||||
[MemoryDiagnoser]
|
[MemoryDiagnoser]
|
||||||
public class TcpPipesBenchmark
|
public class TcpPipesBenchmark : BaseBenchmark
|
||||||
{
|
{
|
||||||
IDuplexPipe _client;
|
IDuplexPipe _client;
|
||||||
IDuplexPipe _server;
|
IDuplexPipe _server;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace MQTTnet.Benchmarks
|
|||||||
[SimpleJob(RuntimeMoniker.Net60)]
|
[SimpleJob(RuntimeMoniker.Net60)]
|
||||||
[RPlotExporter]
|
[RPlotExporter]
|
||||||
[MemoryDiagnoser]
|
[MemoryDiagnoser]
|
||||||
public class TopicFilterComparerBenchmark
|
public class TopicFilterComparerBenchmark : BaseBenchmark
|
||||||
{
|
{
|
||||||
static readonly char[] TopicLevelSeparator = { '/' };
|
static readonly char[] TopicLevelSeparator = { '/' };
|
||||||
|
|
||||||
|
|||||||
@@ -1,31 +1,30 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace MQTTnet.Benchmarks
|
namespace MQTTnet.Benchmarks
|
||||||
{
|
{
|
||||||
public class TopicGenerator
|
public class TopicGenerator
|
||||||
{
|
{
|
||||||
public static void Generate(
|
public static void Generate(
|
||||||
int numPublishers, int numTopicsPerPublisher,
|
int numPublishers,
|
||||||
out Dictionary<string, List<string>> topicsByPublisher,
|
int numTopicsPerPublisher,
|
||||||
out Dictionary<string, List<string>> singleWildcardTopicsByPublisher,
|
out Dictionary<string, List<string>> topicsByPublisher,
|
||||||
out Dictionary<string, List<string>> multiWildcardTopicsByPublisher
|
out Dictionary<string, List<string>> singleWildcardTopicsByPublisher,
|
||||||
)
|
out Dictionary<string, List<string>> multiWildcardTopicsByPublisher)
|
||||||
{
|
{
|
||||||
topicsByPublisher = new Dictionary<string, List<string>>();
|
topicsByPublisher = new Dictionary<string, List<string>>();
|
||||||
singleWildcardTopicsByPublisher = new Dictionary<string, List<string>>();
|
singleWildcardTopicsByPublisher = new Dictionary<string, List<string>>();
|
||||||
multiWildcardTopicsByPublisher = new Dictionary<string, List<string>>();
|
multiWildcardTopicsByPublisher = new Dictionary<string, List<string>>();
|
||||||
|
|
||||||
// Find some reasonable distribution across three topic levels
|
// Find some reasonable distribution across three topic levels
|
||||||
var topicsPerLevel = (int)Math.Pow(numTopicsPerPublisher, (1.0 / 3.0));
|
var topicsPerLevel = (int)Math.Pow(numTopicsPerPublisher, 1.0 / 3.0);
|
||||||
if (topicsPerLevel <= 0)
|
if (topicsPerLevel <= 0)
|
||||||
{
|
{
|
||||||
topicsPerLevel = 1;
|
topicsPerLevel = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int numLevel1Topics = topicsPerLevel;
|
var numLevel1Topics = topicsPerLevel;
|
||||||
int numLevel2Topics = topicsPerLevel;
|
var numLevel2Topics = topicsPerLevel;
|
||||||
|
|
||||||
var maxNumLevel3Topics = 1 + (int)((double)numTopicsPerPublisher / numLevel1Topics / numLevel2Topics);
|
var maxNumLevel3Topics = 1 + (int)((double)numTopicsPerPublisher / numLevel1Topics / numLevel2Topics);
|
||||||
if (maxNumLevel3Topics <= 0)
|
if (maxNumLevel3Topics <= 0)
|
||||||
@@ -35,7 +34,7 @@ namespace MQTTnet.Benchmarks
|
|||||||
|
|
||||||
for (var p = 0; p < numPublishers; ++p)
|
for (var p = 0; p < numPublishers; ++p)
|
||||||
{
|
{
|
||||||
int publisherTopicCount = 0;
|
var publisherTopicCount = 0;
|
||||||
var publisherName = "pub" + p;
|
var publisherName = "pub" + p;
|
||||||
for (var l1 = 0; l1 < numLevel1Topics; ++l1)
|
for (var l1 = 0; l1 < numLevel1Topics; ++l1)
|
||||||
{
|
{
|
||||||
@@ -44,19 +43,22 @@ namespace MQTTnet.Benchmarks
|
|||||||
for (var l3 = 0; l3 < maxNumLevel3Topics; ++l3)
|
for (var l3 = 0; l3 < maxNumLevel3Topics; ++l3)
|
||||||
{
|
{
|
||||||
if (publisherTopicCount >= numTopicsPerPublisher)
|
if (publisherTopicCount >= numTopicsPerPublisher)
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
var topic = string.Format("{0}/building{1}/level{2}/sensor{3}", publisherName, l1 + 1, l2 + 1, l3 + 1);
|
var topic = $"{publisherName}/building{l1 + 1}/level{l2 + 1}/sensor{l3 + 1}";
|
||||||
AddPublisherTopic(publisherName, topic, topicsByPublisher);
|
AddPublisherTopic(publisherName, topic, topicsByPublisher);
|
||||||
|
|
||||||
if (l2 == 0)
|
if (l2 == 0)
|
||||||
{
|
{
|
||||||
var singleWildcardTopic = string.Format("{0}/building{1}/+/sensor{2}", publisherName, l1 + 1, l3 + 1);
|
var singleWildcardTopic = $"{publisherName}/building{l1 + 1}/+/sensor{l3 + 1}";
|
||||||
AddPublisherTopic(publisherName, singleWildcardTopic, singleWildcardTopicsByPublisher);
|
AddPublisherTopic(publisherName, singleWildcardTopic, singleWildcardTopicsByPublisher);
|
||||||
}
|
}
|
||||||
if ((l1 == 0) && (l3 == 0))
|
|
||||||
|
if (l1 == 0 && l3 == 0)
|
||||||
{
|
{
|
||||||
var multiWildcardTopic = string.Format("{0}/+/level{1}/+", publisherName, l2 + 1);
|
var multiWildcardTopic = $"{publisherName}/+/level{l2 + 1}/+";
|
||||||
AddPublisherTopic(publisherName, multiWildcardTopic, multiWildcardTopicsByPublisher);
|
AddPublisherTopic(publisherName, multiWildcardTopic, multiWildcardTopicsByPublisher);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +77,8 @@ namespace MQTTnet.Benchmarks
|
|||||||
topicList = new List<string>();
|
topicList = new List<string>();
|
||||||
topicsByPublisher.Add(publisherName, topicList);
|
topicsByPublisher.Add(publisherName, topicList);
|
||||||
}
|
}
|
||||||
|
|
||||||
topicList.Add(topic);
|
topicList.Add(topic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,7 @@
|
|||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
using BenchmarkDotNet.Attributes;
|
using BenchmarkDotNet.Attributes;
|
||||||
using MQTTnet.Client;
|
using MQTTnet.Client;
|
||||||
using MQTTnet.Server;
|
using MQTTnet.Server;
|
||||||
@@ -7,7 +11,7 @@ using System.Linq;
|
|||||||
namespace MQTTnet.Benchmarks
|
namespace MQTTnet.Benchmarks
|
||||||
{
|
{
|
||||||
[MemoryDiagnoser]
|
[MemoryDiagnoser]
|
||||||
public class UnsubscribeBenchmark
|
public class UnsubscribeBenchmark : BaseBenchmark
|
||||||
{
|
{
|
||||||
MqttServer _mqttServer;
|
MqttServer _mqttServer;
|
||||||
IMqttClient _mqttClient;
|
IMqttClient _mqttClient;
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="BenchmarkDotNet" version="0.10.14" targetFramework="net462" />
|
|
||||||
<package id="BenchmarkDotNet.Core" version="0.10.14" targetFramework="net462" />
|
|
||||||
<package id="BenchmarkDotNet.Toolchains.Roslyn" version="0.10.14" targetFramework="net462" />
|
|
||||||
<package id="Microsoft.CodeAnalysis.Analyzers" version="1.1.0" targetFramework="net462" />
|
|
||||||
<package id="Microsoft.CodeAnalysis.Common" version="2.6.1" targetFramework="net462" />
|
|
||||||
<package id="Microsoft.CodeAnalysis.CSharp" version="2.6.1" targetFramework="net462" />
|
|
||||||
<package id="Microsoft.DotNet.InternalAbstractions" version="1.0.0" targetFramework="net462" />
|
|
||||||
<package id="Microsoft.DotNet.PlatformAbstractions" version="1.1.1" targetFramework="net462" />
|
|
||||||
<package id="Microsoft.Win32.Registry" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.AppContext" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Collections" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Collections.Concurrent" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Collections.Immutable" version="1.3.1" targetFramework="net462" />
|
|
||||||
<package id="System.Console" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Diagnostics.Debug" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Diagnostics.FileVersionInfo" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Diagnostics.StackTrace" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Diagnostics.Tools" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Dynamic.Runtime" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Globalization" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.IO.Compression" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.IO.FileSystem" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.IO.FileSystem.Primitives" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Linq" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Linq.Expressions" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Reflection" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Reflection.Metadata" version="1.4.2" targetFramework="net462" />
|
|
||||||
<package id="System.Resources.ResourceManager" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Runtime" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Runtime.Extensions" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Runtime.InteropServices" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Runtime.Numerics" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Text.Encoding" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Text.Encoding.CodePages" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Text.Encoding.Extensions" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Threading" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Threading.Tasks" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Threading.Tasks.Extensions" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Threading.Tasks.Parallel" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Threading.Thread" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.ValueTuple" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Xml.ReaderWriter" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Xml.XDocument" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Xml.XmlDocument" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Xml.XmlSerializer" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Xml.XPath" version="4.3.0" targetFramework="net462" />
|
|
||||||
<package id="System.Xml.XPath.XDocument" version="4.3.0" targetFramework="net462" />
|
|
||||||
</packages>
|
|
||||||
Reference in New Issue
Block a user