diff --git a/Frameworks/MQTTnet.NetStandard/Internal/MqttApplicationMessageExtensions.cs b/Frameworks/MQTTnet.NetStandard/Internal/MqttApplicationMessageExtensions.cs index b1d1a38..79eb2c4 100644 --- a/Frameworks/MQTTnet.NetStandard/Internal/MqttApplicationMessageExtensions.cs +++ b/Frameworks/MQTTnet.NetStandard/Internal/MqttApplicationMessageExtensions.cs @@ -2,7 +2,7 @@ namespace MQTTnet.Internal { - internal static class MqttApplicationMessageExtensions + public static class MqttApplicationMessageExtensions { public static MqttApplicationMessage ToApplicationMessage(this MqttPublishPacket publishPacket) { diff --git a/Tests/MQTTnet.Core.Tests/TestMqttChannel.cs b/Frameworks/MQTTnet.NetStandard/Internal/TestMqttChannel.cs similarity index 96% rename from Tests/MQTTnet.Core.Tests/TestMqttChannel.cs rename to Frameworks/MQTTnet.NetStandard/Internal/TestMqttChannel.cs index 2b4914b..b380b08 100644 --- a/Tests/MQTTnet.Core.Tests/TestMqttChannel.cs +++ b/Frameworks/MQTTnet.NetStandard/Internal/TestMqttChannel.cs @@ -3,7 +3,7 @@ using System.Threading; using System.Threading.Tasks; using MQTTnet.Channel; -namespace MQTTnet.Core.Tests +namespace MQTTnet.Core.Internal { public class TestMqttChannel : IMqttChannel { diff --git a/Tests/MQTTnet.Benchmarks/MQTTnet.Benchmarks.csproj b/Tests/MQTTnet.Benchmarks/MQTTnet.Benchmarks.csproj index 4977311..3b52bba 100644 --- a/Tests/MQTTnet.Benchmarks/MQTTnet.Benchmarks.csproj +++ b/Tests/MQTTnet.Benchmarks/MQTTnet.Benchmarks.csproj @@ -150,6 +150,7 @@ + diff --git a/Tests/MQTTnet.Benchmarks/Program.cs b/Tests/MQTTnet.Benchmarks/Program.cs index 965ddb5..ad2c363 100644 --- a/Tests/MQTTnet.Benchmarks/Program.cs +++ b/Tests/MQTTnet.Benchmarks/Program.cs @@ -1,5 +1,7 @@ using System; +using System.Threading; using BenchmarkDotNet.Running; +using MQTTnet.Diagnostics; namespace MQTTnet.Benchmarks { @@ -7,7 +9,23 @@ namespace MQTTnet.Benchmarks { public static void Main(string[] args) { - var summary = BenchmarkRunner.Run(); + Console.WriteLine($"MQTTnet - BenchmarkApp.{TargetFrameworkInfoProvider.TargetFramework}"); + Console.WriteLine("1 = MessageProcessingBenchmark"); + Console.WriteLine("2 = SerializerBenchmark"); + + var pressedKey = Console.ReadKey(true); + switch (pressedKey.KeyChar) + { + case '1': + BenchmarkRunner.Run(); + break; + case '2': + BenchmarkRunner.Run(); + break; + default: + break; + } + Console.ReadLine(); } } diff --git a/Tests/MQTTnet.Benchmarks/SerializerBenchmark.cs b/Tests/MQTTnet.Benchmarks/SerializerBenchmark.cs new file mode 100644 index 0000000..bcfff1c --- /dev/null +++ b/Tests/MQTTnet.Benchmarks/SerializerBenchmark.cs @@ -0,0 +1,74 @@ +using BenchmarkDotNet.Attributes; +using MQTTnet.Client; +using MQTTnet.Packets; +using MQTTnet.Serializer; +using MQTTnet.Internal; +using MQTTnet.Server; +using BenchmarkDotNet.Attributes.Jobs; +using BenchmarkDotNet.Attributes.Exporters; +using System; +using System.Threading; +using System.IO; +using MQTTnet.Core.Internal; + +namespace MQTTnet.Benchmarks +{ + [ClrJob] + [RPlotExporter] + [MemoryDiagnoser] + public class SerializerBenchmark + { + private MqttBasePacket _packet; + private ArraySegment _serializedPacket; + private MqttPacketSerializer _serializer; + + [GlobalSetup] + public void Setup() + { + var message = new MqttApplicationMessageBuilder() + .WithTopic("A") + .Build(); + + _packet = message.ToPublishPacket(); + _serializer = new MqttPacketSerializer(); + _serializedPacket = _serializer.Serialize(_packet); + } + + [Benchmark] + public void Serialize_10000_Messages() + { + for (var i = 0; i < 10000; i++) + { + _serializer.Serialize(_packet); + } + } + + [Benchmark] + public void Deserialize_10000_Messages() + { + for (var i = 0; i < 10000; i++) + { + using (var headerStream = new MemoryStream(Join(_serializedPacket))) + { + var header = MqttPacketReader.ReadHeaderAsync(new TestMqttChannel(headerStream), CancellationToken.None).GetAwaiter().GetResult(); + + using (var bodyStream = new MemoryStream(Join(_serializedPacket), (int)headerStream.Position, header.BodyLength)) + { + _serializer.Deserialize(header, bodyStream); + } + } + } + } + + private static byte[] Join(params ArraySegment[] chunks) + { + var buffer = new MemoryStream(); + foreach (var chunk in chunks) + { + buffer.Write(chunk.Array, chunk.Offset, chunk.Count); + } + + return buffer.ToArray(); + } + } +} diff --git a/Tests/MQTTnet.Core.Tests/ExtensionTests.cs b/Tests/MQTTnet.Core.Tests/ExtensionTests.cs index daeea62..696cfa3 100644 --- a/Tests/MQTTnet.Core.Tests/ExtensionTests.cs +++ b/Tests/MQTTnet.Core.Tests/ExtensionTests.cs @@ -14,20 +14,20 @@ namespace MQTTnet.Core.Tests [TestMethod] public async Task TimeoutAfter() { - await Internal.TaskExtensions.TimeoutAfter(ct => Task.Delay(TimeSpan.FromMilliseconds(500), ct), TimeSpan.FromMilliseconds(100), CancellationToken.None); + await MQTTnet.Internal.TaskExtensions.TimeoutAfter(ct => Task.Delay(TimeSpan.FromMilliseconds(500), ct), TimeSpan.FromMilliseconds(100), CancellationToken.None); } [ExpectedException(typeof(MqttCommunicationTimedOutException))] [TestMethod] public async Task TimeoutAfterWithResult() { - await Internal.TaskExtensions.TimeoutAfter(ct => Task.Delay(TimeSpan.FromMilliseconds(500), ct).ContinueWith(t => 5, ct), TimeSpan.FromMilliseconds(100), CancellationToken.None); + await MQTTnet.Internal.TaskExtensions.TimeoutAfter(ct => Task.Delay(TimeSpan.FromMilliseconds(500), ct).ContinueWith(t => 5, ct), TimeSpan.FromMilliseconds(100), CancellationToken.None); } [TestMethod] public async Task TimeoutAfterCompleteInTime() { - var result = await Internal.TaskExtensions.TimeoutAfter(ct => Task.Delay(TimeSpan.FromMilliseconds(100), ct).ContinueWith(t => 5, ct), TimeSpan.FromMilliseconds(500), CancellationToken.None); + var result = await MQTTnet.Internal.TaskExtensions.TimeoutAfter(ct => Task.Delay(TimeSpan.FromMilliseconds(100), ct).ContinueWith(t => 5, ct), TimeSpan.FromMilliseconds(500), CancellationToken.None); Assert.AreEqual(5, result); } @@ -36,7 +36,7 @@ namespace MQTTnet.Core.Tests { try { - await Internal.TaskExtensions.TimeoutAfter(ct => Task.Run(() => + await MQTTnet.Internal.TaskExtensions.TimeoutAfter(ct => Task.Run(() => { var iis = new int[0]; iis[1] = 0; @@ -55,7 +55,7 @@ namespace MQTTnet.Core.Tests { try { - await Internal.TaskExtensions.TimeoutAfter(ct => Task.Run(() => + await MQTTnet.Internal.TaskExtensions.TimeoutAfter(ct => Task.Run(() => { var iis = new int[0]; iis[1] = 0; @@ -76,7 +76,7 @@ namespace MQTTnet.Core.Tests var tasks = Enumerable.Range(0, 100000) .Select(i => { - return Internal.TaskExtensions.TimeoutAfter(ct => Task.Delay(TimeSpan.FromMilliseconds(1), ct), TimeSpan.FromMinutes(1), CancellationToken.None); + return MQTTnet.Internal.TaskExtensions.TimeoutAfter(ct => Task.Delay(TimeSpan.FromMilliseconds(1), ct), TimeSpan.FromMinutes(1), CancellationToken.None); }); await Task.WhenAll(tasks); diff --git a/Tests/MQTTnet.Core.Tests/MqttPacketReaderTests.cs b/Tests/MQTTnet.Core.Tests/MqttPacketReaderTests.cs index ca48ad9..72a675b 100644 --- a/Tests/MQTTnet.Core.Tests/MqttPacketReaderTests.cs +++ b/Tests/MQTTnet.Core.Tests/MqttPacketReaderTests.cs @@ -1,6 +1,7 @@ using System.IO; using System.Threading; using Microsoft.VisualStudio.TestTools.UnitTesting; +using MQTTnet.Core.Internal; using MQTTnet.Serializer; namespace MQTTnet.Core.Tests diff --git a/Tests/MQTTnet.Core.Tests/MqttPacketSerializerTests.cs b/Tests/MQTTnet.Core.Tests/MqttPacketSerializerTests.cs index 580bc4d..a45736d 100644 --- a/Tests/MQTTnet.Core.Tests/MqttPacketSerializerTests.cs +++ b/Tests/MQTTnet.Core.Tests/MqttPacketSerializerTests.cs @@ -3,6 +3,7 @@ using System.IO; using System.Text; using System.Threading; using Microsoft.VisualStudio.TestTools.UnitTesting; +using MQTTnet.Core.Internal; using MQTTnet.Packets; using MQTTnet.Protocol; using MQTTnet.Serializer;