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.
 
 
 
 

90 lines
3.1 KiB

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