benchmark_matchers_test.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package strmatcher_test
  2. import (
  3. "strconv"
  4. "testing"
  5. "github.com/v2fly/v2ray-core/v5/common"
  6. . "github.com/v2fly/v2ray-core/v5/common/strmatcher"
  7. )
  8. func BenchmarkFullMatcher(b *testing.B) {
  9. b.Run("SimpleMatcherGroup------", func(b *testing.B) {
  10. benchmarkMatcherType(b, Full, func() MatcherGroup {
  11. return new(SimpleMatcherGroup)
  12. })
  13. })
  14. b.Run("FullMatcherGroup--------", func(b *testing.B) {
  15. benchmarkMatcherType(b, Full, func() MatcherGroup {
  16. return NewFullMatcherGroup()
  17. })
  18. })
  19. b.Run("ACAutomationMatcherGroup", func(b *testing.B) {
  20. benchmarkMatcherType(b, Full, func() MatcherGroup {
  21. return NewACAutomatonMatcherGroup()
  22. })
  23. })
  24. b.Run("MphMatcherGroup---------", func(b *testing.B) {
  25. benchmarkMatcherType(b, Full, func() MatcherGroup {
  26. return NewMphMatcherGroup()
  27. })
  28. })
  29. }
  30. func BenchmarkDomainMatcher(b *testing.B) {
  31. b.Run("SimpleMatcherGroup------", func(b *testing.B) {
  32. benchmarkMatcherType(b, Domain, func() MatcherGroup {
  33. return new(SimpleMatcherGroup)
  34. })
  35. })
  36. b.Run("DomainMatcherGroup------", func(b *testing.B) {
  37. benchmarkMatcherType(b, Domain, func() MatcherGroup {
  38. return NewDomainMatcherGroup()
  39. })
  40. })
  41. b.Run("ACAutomationMatcherGroup", func(b *testing.B) {
  42. benchmarkMatcherType(b, Domain, func() MatcherGroup {
  43. return NewACAutomatonMatcherGroup()
  44. })
  45. })
  46. b.Run("MphMatcherGroup---------", func(b *testing.B) {
  47. benchmarkMatcherType(b, Domain, func() MatcherGroup {
  48. return NewMphMatcherGroup()
  49. })
  50. })
  51. }
  52. func BenchmarkSubstrMatcher(b *testing.B) {
  53. b.Run("SimpleMatcherGroup------", func(b *testing.B) {
  54. benchmarkMatcherType(b, Substr, func() MatcherGroup {
  55. return new(SimpleMatcherGroup)
  56. })
  57. })
  58. b.Run("SubstrMatcherGroup------", func(b *testing.B) {
  59. benchmarkMatcherType(b, Substr, func() MatcherGroup {
  60. return new(SubstrMatcherGroup)
  61. })
  62. })
  63. b.Run("ACAutomationMatcherGroup", func(b *testing.B) {
  64. benchmarkMatcherType(b, Substr, func() MatcherGroup {
  65. return NewACAutomatonMatcherGroup()
  66. })
  67. })
  68. }
  69. // Utility functions for benchmark
  70. func benchmarkMatcherType(b *testing.B, t Type, ctor func() MatcherGroup) {
  71. b.Run("Match", func(b *testing.B) {
  72. b.Run("Succ", func(b *testing.B) {
  73. benchmarkMatch(b, ctor(), map[Type]bool{t: true})
  74. })
  75. b.Run("Fail", func(b *testing.B) {
  76. benchmarkMatch(b, ctor(), map[Type]bool{t: false})
  77. })
  78. })
  79. b.Run("MatchAny", func(b *testing.B) {
  80. b.Run("Succ", func(b *testing.B) {
  81. benchmarkMatchAny(b, ctor(), map[Type]bool{t: true})
  82. })
  83. b.Run("Fail", func(b *testing.B) {
  84. benchmarkMatchAny(b, ctor(), map[Type]bool{t: false})
  85. })
  86. })
  87. }
  88. func benchmarkMatch(b *testing.B, g MatcherGroup, enabledTypes map[Type]bool) {
  89. prepareMatchers(g, enabledTypes)
  90. b.ResetTimer()
  91. for i := 0; i < b.N; i++ {
  92. _ = g.Match("0.v2fly.org")
  93. }
  94. }
  95. func benchmarkMatchAny(b *testing.B, g MatcherGroup, enabledTypes map[Type]bool) {
  96. prepareMatchers(g, enabledTypes)
  97. b.ResetTimer()
  98. for i := 0; i < b.N; i++ {
  99. _ = g.MatchAny("0.v2fly.org")
  100. }
  101. }
  102. func prepareMatchers(g MatcherGroup, enabledTypes map[Type]bool) {
  103. for matcherType, hasMatch := range enabledTypes {
  104. switch matcherType {
  105. case Domain:
  106. if hasMatch {
  107. AddMatcherToGroup(g, DomainMatcher("v2fly.org"), 0)
  108. }
  109. for i := 1; i < 1024; i++ {
  110. AddMatcherToGroup(g, DomainMatcher(strconv.Itoa(i)+".v2fly.org"), uint32(i))
  111. }
  112. case Full:
  113. if hasMatch {
  114. AddMatcherToGroup(g, FullMatcher("0.v2fly.org"), 0)
  115. }
  116. for i := 1; i < 64; i++ {
  117. AddMatcherToGroup(g, FullMatcher(strconv.Itoa(i)+".v2fly.org"), uint32(i))
  118. }
  119. case Substr:
  120. if hasMatch {
  121. AddMatcherToGroup(g, SubstrMatcher("v2fly.org"), 0)
  122. }
  123. for i := 1; i < 4; i++ {
  124. AddMatcherToGroup(g, SubstrMatcher(strconv.Itoa(i)+".v2fly.org"), uint32(i))
  125. }
  126. case Regex:
  127. matcher, err := Regex.New("^[^.]*$") // Dotless domain matcher automatically inserted in DNS app when "localhost" DNS is used.
  128. common.Must(err)
  129. AddMatcherToGroup(g, matcher, 0)
  130. }
  131. }
  132. if g, ok := g.(buildable); ok {
  133. common.Must(g.Build())
  134. }
  135. }
  136. type buildable interface {
  137. Build() error
  138. }