Files
MQTTnet/Tests/MQTTnet.Benchmarks/TopicFilterComparerBenchmark.cs
T
2021-09-26 11:05:00 +02:00

91 lines
3.2 KiB
C#

using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using System;
using MQTTnet.Server.Internal;
namespace MQTTnet.Benchmarks
{
[SimpleJob(RuntimeMoniker.Net461)]
[RPlotExporter]
[MemoryDiagnoser]
public class TopicFilterComparerBenchmark
{
static readonly char[] TopicLevelSeparator = { '/' };
[GlobalSetup]
public void Setup()
{
}
[Benchmark]
public void MqttTopicFilterComparer_10000_StringSplitMethod()
{
for (var i = 0; i < 10000; i++)
{
LegacyMethodByStringSplit("sport/tennis/player1", "sport/#");
LegacyMethodByStringSplit("sport/tennis/player1/ranking", "sport/#/ranking");
LegacyMethodByStringSplit("sport/tennis/player1/score/wimbledon", "sport/+/player1/#");
LegacyMethodByStringSplit("sport/tennis/player1", "sport/tennis/+");
LegacyMethodByStringSplit("/finance", "+/+");
LegacyMethodByStringSplit("/finance", "/+");
LegacyMethodByStringSplit("/finance", "+");
}
}
[Benchmark]
public void MqttTopicFilterComparer_10000_LoopMethod()
{
for (var i = 0; i < 10000; i++)
{
MqttTopicFilterComparer.IsMatch("sport/tennis/player1", "sport/#");
MqttTopicFilterComparer.IsMatch("sport/tennis/player1/ranking", "sport/#/ranking");
MqttTopicFilterComparer.IsMatch("sport/tennis/player1/score/wimbledon", "sport/+/player1/#");
MqttTopicFilterComparer.IsMatch("sport/tennis/player1", "sport/tennis/+");
MqttTopicFilterComparer.IsMatch("/finance", "+/+");
MqttTopicFilterComparer.IsMatch("/finance", "/+");
MqttTopicFilterComparer.IsMatch("/finance", "+");
}
}
static bool LegacyMethodByStringSplit(string topic, string filter)
{
if (topic == null) throw new ArgumentNullException(nameof(topic));
if (filter == null) throw new ArgumentNullException(nameof(filter));
if (string.Equals(topic, filter, StringComparison.Ordinal))
{
return true;
}
var fragmentsTopic = topic.Split(TopicLevelSeparator, StringSplitOptions.None);
var fragmentsFilter = filter.Split(TopicLevelSeparator, StringSplitOptions.None);
// # > In either case it MUST be the last character specified in the Topic Filter [MQTT-4.7.1-2].
for (var i = 0; i < fragmentsFilter.Length; i++)
{
if (fragmentsFilter[i] == "+")
{
continue;
}
if (fragmentsFilter[i] == "#")
{
return true;
}
if (i >= fragmentsTopic.Length)
{
return false;
}
if (!string.Equals(fragmentsFilter[i], fragmentsTopic[i], StringComparison.Ordinal))
{
return false;
}
}
return fragmentsTopic.Length == fragmentsFilter.Length;
}
}
}