Merge pull request #256 from JanEggers/AllocationBenchmark

added benchmark for serializers
This commit is contained in:
Christian
2018-05-10 19:58:30 +02:00
committed by GitHub
8 changed files with 104 additions and 9 deletions
@@ -2,7 +2,7 @@
namespace MQTTnet.Internal namespace MQTTnet.Internal
{ {
internal static class MqttApplicationMessageExtensions public static class MqttApplicationMessageExtensions
{ {
public static MqttApplicationMessage ToApplicationMessage(this MqttPublishPacket publishPacket) public static MqttApplicationMessage ToApplicationMessage(this MqttPublishPacket publishPacket)
{ {
@@ -3,7 +3,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MQTTnet.Channel; using MQTTnet.Channel;
namespace MQTTnet.Core.Tests namespace MQTTnet.Core.Internal
{ {
public class TestMqttChannel : IMqttChannel public class TestMqttChannel : IMqttChannel
{ {
@@ -150,6 +150,7 @@
<Compile Include="MessageProcessingBenchmark.cs" /> <Compile Include="MessageProcessingBenchmark.cs" />
<Compile Include="Program.cs" /> <Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SerializerBenchmark.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="App.config" /> <None Include="App.config" />
+19 -1
View File
@@ -1,5 +1,7 @@
using System; using System;
using System.Threading;
using BenchmarkDotNet.Running; using BenchmarkDotNet.Running;
using MQTTnet.Diagnostics;
namespace MQTTnet.Benchmarks namespace MQTTnet.Benchmarks
{ {
@@ -7,7 +9,23 @@ namespace MQTTnet.Benchmarks
{ {
public static void Main(string[] args) public static void Main(string[] args)
{ {
var summary = BenchmarkRunner.Run<MessageProcessingBenchmark>(); 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<MessageProcessingBenchmark>();
break;
case '2':
BenchmarkRunner.Run<SerializerBenchmark>();
break;
default:
break;
}
Console.ReadLine(); Console.ReadLine();
} }
} }
@@ -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<byte> _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<byte>[] chunks)
{
var buffer = new MemoryStream();
foreach (var chunk in chunks)
{
buffer.Write(chunk.Array, chunk.Offset, chunk.Count);
}
return buffer.ToArray();
}
}
}
+6 -6
View File
@@ -14,20 +14,20 @@ namespace MQTTnet.Core.Tests
[TestMethod] [TestMethod]
public async Task TimeoutAfter() 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))] [ExpectedException(typeof(MqttCommunicationTimedOutException))]
[TestMethod] [TestMethod]
public async Task TimeoutAfterWithResult() 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] [TestMethod]
public async Task TimeoutAfterCompleteInTime() 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); Assert.AreEqual(5, result);
} }
@@ -36,7 +36,7 @@ namespace MQTTnet.Core.Tests
{ {
try try
{ {
await Internal.TaskExtensions.TimeoutAfter(ct => Task.Run(() => await MQTTnet.Internal.TaskExtensions.TimeoutAfter(ct => Task.Run(() =>
{ {
var iis = new int[0]; var iis = new int[0];
iis[1] = 0; iis[1] = 0;
@@ -55,7 +55,7 @@ namespace MQTTnet.Core.Tests
{ {
try try
{ {
await Internal.TaskExtensions.TimeoutAfter(ct => Task.Run(() => await MQTTnet.Internal.TaskExtensions.TimeoutAfter(ct => Task.Run(() =>
{ {
var iis = new int[0]; var iis = new int[0];
iis[1] = 0; iis[1] = 0;
@@ -76,7 +76,7 @@ namespace MQTTnet.Core.Tests
var tasks = Enumerable.Range(0, 100000) var tasks = Enumerable.Range(0, 100000)
.Select(i => .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); await Task.WhenAll(tasks);
@@ -1,6 +1,7 @@
using System.IO; using System.IO;
using System.Threading; using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using MQTTnet.Core.Internal;
using MQTTnet.Serializer; using MQTTnet.Serializer;
namespace MQTTnet.Core.Tests namespace MQTTnet.Core.Tests
@@ -3,6 +3,7 @@ using System.IO;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using MQTTnet.Core.Internal;
using MQTTnet.Packets; using MQTTnet.Packets;
using MQTTnet.Protocol; using MQTTnet.Protocol;
using MQTTnet.Serializer; using MQTTnet.Serializer;