1- import _StringProcessing
1+ @_spi ( RegexBenchmark) import _StringProcessing
2+ @_implementationOnly import _RegexParser
23import Foundation
34
4- protocol RegexBenchmark {
5+ protocol RegexBenchmark : Debug {
56 var name : String { get }
67 func run( )
7- func debug( )
88}
99
10- struct Benchmark : RegexBenchmark {
10+ protocol SwiftRegexBenchmark : RegexBenchmark {
11+ var regex : Regex < AnyRegexOutput > { get set }
12+ var pattern : String ? { get }
13+ }
14+
15+ extension SwiftRegexBenchmark {
16+ mutating func compile( ) {
17+ let _ = regex. _forceAction ( . recompile)
18+ }
19+ mutating func parse( ) -> Bool {
20+ guard let s = pattern else {
21+ return false
22+ }
23+
24+ do {
25+ let _ = try _RegexParser. parse ( s, . traditional)
26+ return true
27+ } catch {
28+ return false
29+ }
30+ }
31+ mutating func enableTracing( ) {
32+ let _ = regex. _forceAction ( . addOptions( . enableTracing) )
33+ }
34+ mutating func enableMetrics( ) {
35+ let _ = regex. _forceAction ( . addOptions( [ . enableMetrics] ) )
36+ }
37+ }
38+
39+ struct Benchmark : SwiftRegexBenchmark {
1140 let name : String
12- let regex : Regex < AnyRegexOutput >
41+ var regex : Regex < AnyRegexOutput >
42+ let pattern : String ?
1343 let type : MatchType
1444 let target : String
1545
@@ -52,11 +82,12 @@ struct NSBenchmark: RegexBenchmark {
5282}
5383
5484/// A benchmark running a regex on strings in input set
55- struct InputListBenchmark : RegexBenchmark {
85+ struct InputListBenchmark : SwiftRegexBenchmark {
5686 let name : String
57- let regex : Regex < AnyRegexOutput >
87+ var regex : Regex < AnyRegexOutput >
88+ let pattern : String ?
5889 let targets : [ String ]
59-
90+
6091 func run( ) {
6192 for target in targets {
6293 blackHole ( target. wholeMatch ( of: regex) )
@@ -78,7 +109,7 @@ struct InputListNSBenchmark: RegexBenchmark {
78109 func range( in target: String ) -> NSRange {
79110 NSRange ( target. startIndex..< target. endIndex, in: target)
80111 }
81-
112+
82113 func run( ) {
83114 for target in targets {
84115 let range = range ( in: target)
@@ -89,6 +120,9 @@ struct InputListNSBenchmark: RegexBenchmark {
89120
90121/// A benchmark meant to be ran across multiple engines
91122struct CrossBenchmark {
123+ /// Suffix added onto NSRegularExpression benchmarks
124+ static var nsSuffix : String { " _NS " }
125+
92126 /// The base name of the benchmark
93127 var baseName : String
94128
@@ -123,11 +157,12 @@ struct CrossBenchmark {
123157 Benchmark (
124158 name: baseName + " Whole " ,
125159 regex: swiftRegex,
160+ pattern: regex,
126161 type: . whole,
127162 target: input) )
128163 runner. register (
129164 NSBenchmark (
130- name: baseName + " Whole_NS " ,
165+ name: baseName + " Whole " + CrossBenchmark . nsSuffix ,
131166 regex: nsRegex,
132167 type: . first,
133168 target: input) )
@@ -136,24 +171,26 @@ struct CrossBenchmark {
136171 Benchmark (
137172 name: baseName + " All " ,
138173 regex: swiftRegex,
174+ pattern: regex,
139175 type: . allMatches,
140176 target: input) )
141177 runner. register (
142178 NSBenchmark (
143- name: baseName + " All_NS " ,
179+ name: baseName + " All " + CrossBenchmark . nsSuffix ,
144180 regex: nsRegex,
145181 type: . allMatches,
146182 target: input) )
147- if includeFirst {
183+ if includeFirst || runner . includeFirstOverride {
148184 runner. register (
149185 Benchmark (
150186 name: baseName + " First " ,
151187 regex: swiftRegex,
188+ pattern: regex,
152189 type: . first,
153190 target: input) )
154191 runner. register (
155192 NSBenchmark (
156- name: baseName + " First_NS " ,
193+ name: baseName + " First " + CrossBenchmark . nsSuffix ,
157194 regex: nsRegex,
158195 type: . first,
159196 target: input) )
@@ -178,10 +215,11 @@ struct CrossInputListBenchmark {
178215 runner. register ( InputListBenchmark (
179216 name: baseName,
180217 regex: swiftRegex,
218+ pattern: regex,
181219 targets: inputs
182220 ) )
183221 runner. register ( InputListNSBenchmark (
184- name: baseName + " NS " ,
222+ name: baseName + CrossBenchmark . nsSuffix ,
185223 regex: regex,
186224 targets: inputs
187225 ) )
0 commit comments