Skip to content

Commit 742b566

Browse files
authored
fix: Fix comparisons of absolute thresholds, add helpers for defining them (#32)
Fixes #31
1 parent febff8e commit 742b566

File tree

5 files changed

+74
-14
lines changed

5 files changed

+74
-14
lines changed

Plugins/BenchmarkTool/BenchmarkTool+Baselines.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -234,10 +234,10 @@ extension BenchmarkBaseline: Equatable {
234234
var betterOrEqualForIdentifier = true
235235

236236
for (lhsBenchmarkIdentifier, lhsBenchmarkResults) in lhs.results {
237-
/* if printOutput {
238-
print("Checking for threshold violations for `\(lhsBenchmarkIdentifier.target):\(lhsBenchmarkIdentifier.name)`.")
239-
}
240-
*/
237+
/* if printOutput {
238+
print("Checking for threshold violations for `\(lhsBenchmarkIdentifier.target):\(lhsBenchmarkIdentifier.name)`.")
239+
}
240+
*/
241241
for lhsBenchmarkResult in lhsBenchmarkResults {
242242
if let rhsResults = rhs.results.first(where: { $0.key == lhsBenchmarkIdentifier }) {
243243
if let rhsBenchmarkResult = rhsResults.value.first(where: { $0.metric == lhsBenchmarkResult.metric }) {

Sources/Benchmark/BenchmarkResult+Defaults.swift

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616
// swiftlint:disable identifier_name
1717

1818
public extension BenchmarkResult {
19-
typealias PercentileRelativeThresholds = [BenchmarkResult.Percentile: Double]
20-
typealias PercentileAbsoluteThresholds = [BenchmarkResult.Percentile: Int]
19+
typealias PercentileRelativeThreshold = Double
20+
typealias PercentileAbsoluteThreshold = Int
21+
typealias PercentileRelativeThresholds = [BenchmarkResult.Percentile: PercentileRelativeThreshold]
22+
typealias PercentileAbsoluteThresholds = [BenchmarkResult.Percentile: PercentileAbsoluteThreshold]
2123

2224
struct PercentileThresholds: Codable {
2325
public init(relative: BenchmarkResult.PercentileRelativeThresholds = .none,
@@ -117,3 +119,54 @@ public extension BenchmarkResult.PercentileThresholds {
117119
BenchmarkResult.PercentileThresholds()
118120
}
119121
}
122+
123+
// Convenience functions for defining absolute thresholds
124+
public extension BenchmarkResult.PercentileAbsoluteThreshold {
125+
static func hours(_ hours: Int) -> BenchmarkResult.PercentileAbsoluteThreshold {
126+
hours * 1_000_000_000 * 60 * 60
127+
}
128+
129+
static func minutes(_ minutes: Int) -> BenchmarkResult.PercentileAbsoluteThreshold {
130+
minutes * 1_000_000_000 * 60
131+
}
132+
133+
static func seconds(_ seconds: Int) -> BenchmarkResult.PercentileAbsoluteThreshold {
134+
seconds * 1_000_000_000
135+
}
136+
137+
static func milliseconds(_ milliseconds: Int) -> BenchmarkResult.PercentileAbsoluteThreshold {
138+
milliseconds * 1_000_000
139+
}
140+
141+
static func microseconds(_ microseconds: Int) -> BenchmarkResult.PercentileAbsoluteThreshold {
142+
microseconds * 1_000
143+
}
144+
145+
static func nanoseconds(_ value: Int) -> BenchmarkResult.PercentileAbsoluteThreshold {
146+
value
147+
}
148+
149+
static func nanoseconds(_ value: UInt) -> BenchmarkResult.PercentileAbsoluteThreshold {
150+
Int(value)
151+
}
152+
153+
static func giga(_ value: Int) -> BenchmarkResult.PercentileAbsoluteThreshold {
154+
value * 1_000_000_000
155+
}
156+
157+
static func mega(_ value: Int) -> BenchmarkResult.PercentileAbsoluteThreshold {
158+
value * 1_000_000
159+
}
160+
161+
static func kilo(_ value: Int) -> BenchmarkResult.PercentileAbsoluteThreshold {
162+
value * 1_000
163+
}
164+
165+
static func count(_ value: Int) -> BenchmarkResult.PercentileAbsoluteThreshold {
166+
value
167+
}
168+
169+
static func count(_ value: UInt) -> BenchmarkResult.PercentileAbsoluteThreshold {
170+
Int(value)
171+
}
172+
}

Sources/Benchmark/BenchmarkResult.swift

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ public struct BenchmarkResult: Codable, Comparable, Equatable {
131131

132132
return allIsLess
133133
}
134-
134+
// swiftlint:disable function_body_length
135135
public func betterResultsOrEqual(than otherResult: BenchmarkResult,
136136
thresholds: BenchmarkResult.PercentileThresholds = .default,
137137
printOutput: Bool = false) -> Bool {
@@ -146,11 +146,12 @@ public struct BenchmarkResult: Codable, Comparable, Equatable {
146146
}
147147

148148
rhs.scaleResults(to: lhs)
149-
149+
// swiftlint:disable function_parameter_count
150150
func worseResult(_ lhs: Int,
151151
_ rhs: Int,
152152
_ percentile: BenchmarkResult.Percentile,
153153
_ thresholds: BenchmarkResult.PercentileThresholds,
154+
_ scalingFactor: Int,
154155
_ printOutput: Bool) -> Bool {
155156
let relativeDifference = (100 - (100.0 * Double(lhs) / Double(rhs)))
156157
let absoluteDifference = lhs - rhs
@@ -161,17 +162,18 @@ public struct BenchmarkResult: Codable, Comparable, Equatable {
161162
if let threshold = thresholds.relative[percentile] {
162163
if reverseComparison ? relativeDifference > threshold : -relativeDifference > threshold {
163164
if printOutput {
164-
print("`\(metric.description)` failed relative threshold check, [\(percentile)] result" +
165+
print("`\(metric.description)` relative threshold violated, [\(percentile)] result" +
165166
" (\(roundToDecimalplaces(abs(relativeDifference), 1))) > threshold (\(threshold))")
166167
}
167168
thresholdViolated = true
168169
}
169170
}
170171

171-
if let threshold = thresholds.absolute[percentile] {
172+
if var threshold = thresholds.absolute[percentile] {
173+
threshold = threshold / (1_000_000_000 / scalingFactor)
172174
if reverseComparison ? -absoluteDifference > threshold : absoluteDifference > threshold {
173175
if printOutput {
174-
print("`\(metric.description)` failed absolute threshold check, [\(percentile)] result" +
176+
print("`\(metric.description)` absolute threshold violated, [\(percentile)] result" +
175177
" (\(abs(absoluteDifference))) > threshold (\(threshold))")
176178
}
177179
thresholdViolated = true
@@ -184,7 +186,12 @@ public struct BenchmarkResult: Codable, Comparable, Equatable {
184186

185187
lhs.percentiles.forEach { percentile, lhsPercentile in
186188
if let rhsPercentile = rhs.percentiles[percentile] {
187-
worse = worseResult(lhsPercentile, rhsPercentile, percentile, thresholds, printOutput) || worse
189+
worse = worseResult(lhsPercentile,
190+
rhsPercentile,
191+
percentile,
192+
thresholds,
193+
lhs.timeUnits.rawValue,
194+
printOutput) || worse
188195
} else {
189196
print("\(rhs.metric) missing value for percentile \(percentile), skipping it.")
190197
}

Tests/BenchmarkTests/BenchmarkResultTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
@testable import BenchmarkSupport
1212
import XCTest
1313

14-
// swiftlint: disable function_body_length
14+
// swiftlint:disable function_body_length
1515
final class BenchmarkResultTests: XCTestCase {
1616
func testBenchmarkResultEquality() throws {
1717
let measurementCount = 100

Tests/BenchmarkTests/BenchmarkRunnerTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ final class BenchmarkRunnerTests: XCTestCase, BenchmarkRunnerReadWrite {
2828
private var readMessage: Int = 0
2929
private var writeCount: Int = 0
3030

31-
// swiftlint: disable test_case_accessibility
31+
// swiftlint:disable test_case_accessibility
3232
internal func write(_: BenchmarkCommandReply) throws {
3333
writeCount += 1
3434
// print("write \(reply)")

0 commit comments

Comments
 (0)