You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

91 lines
3.2 KiB

  1. using BenchmarkDotNet.Attributes;
  2. using BenchmarkDotNet.Jobs;
  3. using MQTTnet.Server;
  4. using System;
  5. namespace MQTTnet.Benchmarks
  6. {
  7. [SimpleJob(RuntimeMoniker.Net461)]
  8. [RPlotExporter]
  9. [MemoryDiagnoser]
  10. public class TopicFilterComparerBenchmark
  11. {
  12. private static readonly char[] TopicLevelSeparator = { '/' };
  13. [GlobalSetup]
  14. public void Setup()
  15. {
  16. }
  17. [Benchmark]
  18. public void MqttTopicFilterComparer_10000_StringSplitMethod()
  19. {
  20. for (var i = 0; i < 10000; i++)
  21. {
  22. LegacyMethodByStringSplit("sport/tennis/player1", "sport/#");
  23. LegacyMethodByStringSplit("sport/tennis/player1/ranking", "sport/#/ranking");
  24. LegacyMethodByStringSplit("sport/tennis/player1/score/wimbledon", "sport/+/player1/#");
  25. LegacyMethodByStringSplit("sport/tennis/player1", "sport/tennis/+");
  26. LegacyMethodByStringSplit("/finance", "+/+");
  27. LegacyMethodByStringSplit("/finance", "/+");
  28. LegacyMethodByStringSplit("/finance", "+");
  29. }
  30. }
  31. [Benchmark]
  32. public void MqttTopicFilterComparer_10000_LoopMethod()
  33. {
  34. for (var i = 0; i < 10000; i++)
  35. {
  36. MqttTopicFilterComparer.IsMatch("sport/tennis/player1", "sport/#");
  37. MqttTopicFilterComparer.IsMatch("sport/tennis/player1/ranking", "sport/#/ranking");
  38. MqttTopicFilterComparer.IsMatch("sport/tennis/player1/score/wimbledon", "sport/+/player1/#");
  39. MqttTopicFilterComparer.IsMatch("sport/tennis/player1", "sport/tennis/+");
  40. MqttTopicFilterComparer.IsMatch("/finance", "+/+");
  41. MqttTopicFilterComparer.IsMatch("/finance", "/+");
  42. MqttTopicFilterComparer.IsMatch("/finance", "+");
  43. }
  44. }
  45. private static bool LegacyMethodByStringSplit(string topic, string filter)
  46. {
  47. if (topic == null) throw new ArgumentNullException(nameof(topic));
  48. if (filter == null) throw new ArgumentNullException(nameof(filter));
  49. if (string.Equals(topic, filter, StringComparison.Ordinal))
  50. {
  51. return true;
  52. }
  53. var fragmentsTopic = topic.Split(TopicLevelSeparator, StringSplitOptions.None);
  54. var fragmentsFilter = filter.Split(TopicLevelSeparator, StringSplitOptions.None);
  55. // # > In either case it MUST be the last character specified in the Topic Filter [MQTT-4.7.1-2].
  56. for (var i = 0; i < fragmentsFilter.Length; i++)
  57. {
  58. if (fragmentsFilter[i] == "+")
  59. {
  60. continue;
  61. }
  62. if (fragmentsFilter[i] == "#")
  63. {
  64. return true;
  65. }
  66. if (i >= fragmentsTopic.Length)
  67. {
  68. return false;
  69. }
  70. if (!string.Equals(fragmentsFilter[i], fragmentsTopic[i], StringComparison.Ordinal))
  71. {
  72. return false;
  73. }
  74. }
  75. return fragmentsTopic.Length == fragmentsFilter.Length;
  76. }
  77. }
  78. }