Skip to content

Add new benchmarks and benchmarker functionality (try 2) #509

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Jun 22, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add debug mode
  • Loading branch information
rctcwyvrn committed Jun 20, 2022
commit bde259b196c668c4677287db3690db16f2b0aef5
17 changes: 12 additions & 5 deletions Sources/RegexBenchmark/Benchmark.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import Foundation
public protocol RegexBenchmark {
var name: String { get }
func run()
func debug()
}

public struct Benchmark: RegexBenchmark {
public let name: String
let regex: Regex<Substring>
let regex: Regex<AnyRegexOutput>
let type: MatchType
let target: String

Expand Down Expand Up @@ -57,9 +58,7 @@ public struct BenchmarkRunner {
let samples: Int

public init(_ suiteName: String) {
self.suiteName = suiteName
self.suite = []
self.samples = 20
self.init(suiteName, 20)
}

public init(_ suiteName: String, _ n: Int) {
Expand Down Expand Up @@ -108,6 +107,14 @@ public struct BenchmarkRunner {
print("- done")
}
}

public func debug() {
print("Debugging")
for b in suite {
print("- \(b.name) \(measure(benchmark: b))")
b.debug()
}
}
}

/// A benchmark meant to be ran across multiple engines
Expand All @@ -130,7 +137,7 @@ struct CrossBenchmark {
var isWhole: Bool = false

func register(_ runner: inout BenchmarkRunner) {
let swiftRegex = try! Regex(regex, as: Substring.self)
let swiftRegex = try! Regex(regex)

let nsPattern = isWhole ? "^" + regex + "$" : regex
let nsRegex: NSRegularExpression
Expand Down
13 changes: 9 additions & 4 deletions Sources/RegexBenchmark/CLI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ struct Runner: ParsableCommand {

@Option(help: "How many samples to collect for each benchmark")
var samples = 20

@Option(help: "Debug benchmark regexes")
var debug = false

func makeRunner() -> BenchmarkRunner {
var benchmark = BenchmarkRunner("RegexBench", samples)
Expand All @@ -20,15 +23,17 @@ struct Runner: ParsableCommand {
benchmark.addHangulSyllable()
return benchmark
}

mutating func run() throws {
var runner = makeRunner()
if !self.specificBenchmarks.isEmpty {
runner.suite = runner.suite.filter { b in specificBenchmarks.contains(b.name) }
}
if profile {
runner.profile()
} else {
runner.run()
switch (profile, debug) {
case (true, true): print("Cannot run both profile and debug")
case (true, false): runner.profile()
case (false, true): runner.debug()
case (false, false): runner.run()
}
}
}
89 changes: 89 additions & 0 deletions Sources/RegexBenchmark/Debug.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
extension Benchmark {
public func debug() {
switch type {
case .whole:
let result = target.wholeMatch(of: regex)
if let match = result {
if match.0.count > 100 {
print("- Match: len = \(match.0.count)")
} else {
print("- Match: \(match.0)")
}
} else {
print("- No match found")
}
case .allMatches:
let results = target.matches(of: regex)
if results.isEmpty {
print("- No matches")
return
}

print("- Total matches: \(results.count)")
if results.count > 10 {
print("# Too many matches, not printing")
return
}

for match in results {
if match.0.count > 100 {
print("- Match: len = \(match.0.count)")
} else {
print("- Match: \(match.0)")
}
}

case .first:
let result = target.firstMatch(of: regex)
if let match = result {
if match.0.count > 100 {
print("- Match: len = \(match.0.count)")
} else {
print("- Match: \(match.0)")
}
} else {
print("- No match found")
return
}
}
}
}

extension NSBenchmark {
public func debug() {
switch type {
case .allMatches:
let results = regex.matches(in: target, range: range)
if results.isEmpty {
print("- No matches")
return
}

print("- Total matches: \(results.count)")
if results.count > 10 {
print("# Too many matches, not printing")
return
}

for m in results {
if m.range.length > 100 {
print("- Match: len = \(m.range.length)")
} else {
print("- Match: \(target[Range(m.range, in: target)!])")
}
}
case .first:
let result = regex.firstMatch(in: target, range: range)
if let match = result {
if match.range.length > 100 {
print("- Match: len = \(match.range.length)")
} else {
print("- Match: \(target[Range(match.range, in: target)!])")
}
} else {
print("- No match found")
return
}
}
}
}