Skip to content

Commit 6a4cfdf

Browse files
authored
Add --filter-not setting (#59)
1 parent 13312ec commit 6a4cfdf

File tree

7 files changed

+60
-8
lines changed

7 files changed

+60
-8
lines changed

README.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,26 @@ Example:
2727
```terminal
2828
$ swift run -c release BenchmarkMinimalExample -h
2929
[3/3] Linking BenchmarkMinimalExample
30-
USAGE: benchmark-command [--allow-debug-build] [--filter <filter>] [--iterations <iterations>] [--warmup-iterations <warmup-iterations>] [--min-time <min-time>] [--max-iterations <max-iterations>]
30+
USAGE: benchmark-command [--allow-debug-build] [--filter <filter>] [--filter-not <filter-not>] [--iterations <iterations>] [--warmup-iterations <warmup-iterations>] [--min-time <min-time>] [--max-iterations <max-iterations>] [--time-unit <time-unit>] [--inverse-time-unit <inverse-time-unit>] [--columns <columns>] [--format <format>]
3131
3232
OPTIONS:
3333
--allow-debug-build Overrides check to verify optimized build.
3434
--filter <filter> Run only benchmarks whose names match the regular expression.
35+
--filter-not <filter-not>
36+
Exclude benchmarks whose names match the regular expression.
3537
--iterations <iterations>
3638
Number of iterations to run.
3739
--warmup-iterations <warmup-iterations>
3840
Number of warm-up iterations to run.
3941
--min-time <min-time> Minimal time to run when automatically detecting number iterations.
4042
--max-iterations <max-iterations>
41-
Maximum number of iterations to run when automatically detecting number iterations.
43+
Maximum number of iterations to run when automatically detecting number
44+
iterations.
45+
--time-unit <time-unit> Time unit used to report the timing results.
46+
--inverse-time-unit <inverse-time-unit>
47+
Inverse time unit used to report throughput results.
48+
--columns <columns> Comma-separated list of column names to show.
49+
--format <format> Output format (valid values are: json, csv, console, none).
4250
-h, --help Show help information.
4351
4452
$ swift run -c release BenchmarkMinimalExample

Sources/Benchmark/BenchmarkArguments.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ public struct BenchmarkArguments: ParsableArguments {
2323
@Option(help: "Run only benchmarks whose names match the regular expression.")
2424
var filter: String?
2525

26+
@Option(help: "Exclude benchmarks whose names match the regular expression.")
27+
var filterNot: String?
28+
2629
@Option(help: "Number of iterations to run.")
2730
var iterations: Int?
2831

@@ -57,6 +60,9 @@ public struct BenchmarkArguments: ParsableArguments {
5760
if let value = filter {
5861
result.append(Filter(value))
5962
}
63+
if let value = filterNot {
64+
result.append(FilterNot(value))
65+
}
6066
if let value = iterations {
6167
result.append(Iterations(value))
6268
}

Sources/Benchmark/BenchmarkFilter.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@
1515
import Foundation
1616

1717
internal struct BenchmarkFilter {
18+
let negate: Bool
1819
let underlying: NSRegularExpression?
1920

20-
init(_ regularExpression: String?) throws {
21+
init(_ regularExpression: String?, negate: Bool) throws {
22+
self.negate = negate
2123
if regularExpression != nil {
2224
self.underlying = try NSRegularExpression(
2325
pattern: regularExpression!,
@@ -33,7 +35,9 @@ internal struct BenchmarkFilter {
3335
} else {
3436
let str = "\(suiteName).\(benchmarkName)"
3537
let range = NSRange(location: 0, length: str.utf16.count)
36-
return underlying!.firstMatch(in: str, range: range) != nil
38+
var result = underlying!.firstMatch(in: str, range: range) != nil
39+
result = negate ? !result : result
40+
return result
3741
}
3842
}
3943
}

Sources/Benchmark/BenchmarkRunner.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,16 @@ public struct BenchmarkRunner {
7474
self.settings,
7575
])
7676

77-
let filter = try BenchmarkFilter(settings.filter)
77+
let filter = try BenchmarkFilter(settings.filter, negate: false)
7878
if !filter.matches(suiteName: suite.name, benchmarkName: benchmark.name) {
7979
return
8080
}
8181

82+
let filterNot = try BenchmarkFilter(settings.filterNot, negate: true)
83+
if !filterNot.matches(suiteName: suite.name, benchmarkName: benchmark.name) {
84+
return
85+
}
86+
8287
progress.report(running: benchmark.name, suite: suite.name)
8388
let totalStart = now()
8489

Sources/Benchmark/BenchmarkSetting.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ public struct Filter: BenchmarkSetting {
5454
}
5555
}
5656

57+
/// A regex string used to exclude benchmarks that should be run.
58+
public struct FilterNot: BenchmarkSetting {
59+
public var value: String
60+
public init(_ value: String) {
61+
self.value = value
62+
}
63+
}
64+
5765
/// A minimal (total) time that iterations has to run
5866
/// to be considered significant.
5967
public struct MinTime: BenchmarkSetting {
@@ -184,6 +192,11 @@ public struct BenchmarkSettings {
184192
return self[Filter.self]?.value
185193
}
186194

195+
/// Convenience accessor for the Filter setting.
196+
public var filterNot: String? {
197+
return self[FilterNot.self]?.value
198+
}
199+
187200
/// Convenience accessor for the MinTime setting.
188201
public var minTime: Double {
189202
if let value = self[MinTime.self]?.value {

Tests/BenchmarkTests/BenchmarkColumnTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ final class BenchmarkColumnTests: XCTestCase {
5555

5656
func testRenamed() {
5757
let time = BenchmarkColumn.registry["time"]!
58-
XCTAssertEqual(time.name, "time")
58+
XCTAssertEqual(time.name, "time")
5959
let mytime = time.renamed("mytime")
6060
XCTAssertEqual(mytime.name, "mytime")
6161
}

Tests/BenchmarkTests/BenchmarkCommandTests.swift

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,34 @@ final class BenchmarkCommandTests: XCTestCase {
4242

4343
func testParseFilter() throws {
4444
AssertParse(["--filter", "bar", "--allow-debug-build"]) { settings in
45-
let filter = try! BenchmarkFilter(settings.filter)
45+
let filter = try! BenchmarkFilter(settings.filter, negate: false)
4646
XCTAssertFalse(filter.matches(suiteName: "foo", benchmarkName: "baz"))
4747
XCTAssert(filter.matches(suiteName: "foo", benchmarkName: "bar"))
4848
}
4949

5050
AssertParse(["--filter", "foo.bar", "--allow-debug-build"]) { settings in
51-
let filter = try! BenchmarkFilter(settings.filter)
51+
let filter = try! BenchmarkFilter(settings.filter, negate: false)
5252
XCTAssertFalse(filter.matches(suiteName: "foo", benchmarkName: "baz"))
5353
XCTAssertFalse(filter.matches(suiteName: "foobar", benchmarkName: "baz"))
5454
XCTAssert(filter.matches(suiteName: "foo", benchmarkName: "bar"))
5555
}
5656
}
5757

58+
func testParseFilterNot() throws {
59+
AssertParse(["--filter-not", "bar", "--allow-debug-build"]) { settings in
60+
let filter = try! BenchmarkFilter(settings.filterNot, negate: true)
61+
XCTAssert(filter.matches(suiteName: "foo", benchmarkName: "baz"))
62+
XCTAssertFalse(filter.matches(suiteName: "foo", benchmarkName: "bar"))
63+
}
64+
65+
AssertParse(["--filter-not", "foo.bar", "--allow-debug-build"]) { settings in
66+
let filter = try! BenchmarkFilter(settings.filterNot, negate: true)
67+
XCTAssert(filter.matches(suiteName: "foo", benchmarkName: "baz"))
68+
XCTAssert(filter.matches(suiteName: "foobar", benchmarkName: "baz"))
69+
XCTAssertFalse(filter.matches(suiteName: "foo", benchmarkName: "bar"))
70+
}
71+
}
72+
5873
func testParseIterations() throws {
5974
AssertParse(["--iterations", "42", "--allow-debug-build"]) { settings in
6075
XCTAssertEqual(settings.iterations, 42)
@@ -113,6 +128,7 @@ final class BenchmarkCommandTests: XCTestCase {
113128
("testAllowDebugBuild", testAllowDebugBuild),
114129
("testDebugBuildError", testDebugBuildError),
115130
("testParseFilter", testParseFilter),
131+
("testParseFilterNot", testParseFilterNot),
116132
("testParseIterations", testParseIterations),
117133
("testParseZeroIterations", testParseZeroIterations),
118134
("testParseWarmupIterations", testParseWarmupIterations),

0 commit comments

Comments
 (0)