Skip to content

Commit

Permalink
fix: Fix absolute comparisons (#123)
Browse files Browse the repository at this point in the history
Fix incorrect scaling of delta absolute comparisons, add one more unit test.
  • Loading branch information
hassila authored Mar 22, 2023
1 parent b558e61 commit 6c80fcf
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 7 deletions.
6 changes: 2 additions & 4 deletions Sources/BenchmarkSupport/BenchmarkResult.swift
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,6 @@ public struct BenchmarkResult: Codable, Comparable, Equatable {
let reverseComparison = metric.polarity == .prefersLarger
var violationDescriptions: [ThresholdDeviation] = []
var thresholdViolated = false

if let threshold = thresholds.relative[percentile] {
if reverseComparison ? relativeDifference > threshold : -relativeDifference > threshold {
let relativeDiff = Statistics.roundToDecimalplaces(abs(relativeDifference), 1)
Expand All @@ -397,8 +396,7 @@ public struct BenchmarkResult: Codable, Comparable, Equatable {
}
}

if var threshold = thresholds.absolute[percentile] {
threshold /= (1_000_000_000 / scalingFactor.rawValue)
if let threshold = thresholds.absolute[percentile] {
if reverseComparison ? -absoluteDifference > threshold : absoluteDifference > threshold {
violationDescriptions.append(ThresholdDeviation(name: name,
target: target,
Expand All @@ -407,7 +405,7 @@ public struct BenchmarkResult: Codable, Comparable, Equatable {
baseValue: normalize(lhs),
comparisonValue: normalize(rhs),
difference: normalize(absoluteDifference),
differenceThreshold: threshold,
differenceThreshold: normalize(threshold),
relative: false,
units: scalingFactor))
thresholdViolated = true
Expand Down
88 changes: 85 additions & 3 deletions Tests/BenchmarkTests/BenchmarkResultTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -173,13 +173,13 @@ final class BenchmarkResultTests: XCTestCase {
firstStatistics.add(200)

let secondStatistics = Statistics()
secondStatistics.add(0)
secondStatistics.add(126)
secondStatistics.add(5)
secondStatistics.add(136)
secondStatistics.add(160)
secondStatistics.add(175)
secondStatistics.add(190)
secondStatistics.add(199)
secondStatistics.add(200)
secondStatistics.add(210)

let relative: BenchmarkThresholds.RelativeThresholds = [.p0: 0.0,
.p25: 0.0,
Expand Down Expand Up @@ -249,6 +249,88 @@ final class BenchmarkResultTests: XCTestCase {
XCTAssert(betterOrEqual)
}

func testBenchmarkAbsoluteThresholds() throws {
let firstStatistics = Statistics()
firstStatistics.add(0)
firstStatistics.add(125)
firstStatistics.add(150)
firstStatistics.add(175)
firstStatistics.add(190)
firstStatistics.add(199)
firstStatistics.add(200)

let secondStatistics = Statistics()
secondStatistics.add(5)
secondStatistics.add(136)
secondStatistics.add(160)
secondStatistics.add(175)
secondStatistics.add(190)
secondStatistics.add(199)
secondStatistics.add(210)

let thirdStatistics = Statistics()
thirdStatistics.add(1_501)
thirdStatistics.add(1_501)
thirdStatistics.add(1_501)
thirdStatistics.add(1_501)
thirdStatistics.add(1_501)

let absolute: BenchmarkThresholds.AbsoluteThresholds = [.p0: 1,
.p25: 1,
.p50: 1,
.p75: 1,
.p90: 1,
.p99: 1]

let absoluteThresholds = BenchmarkThresholds(absolute: absolute)

let absoluteTwo: BenchmarkThresholds.AbsoluteThresholds = [.p0: 1_500,
.p25: 1_500,
.p50: 1_500,
.p75: 1_500,
.p90: 1_500,
.p99: 1_500]

let absoluteThresholdsTwo = BenchmarkThresholds(absolute: absoluteTwo)

let firstResult = BenchmarkResult(metric: .cpuUser,
timeUnits: .nanoseconds,
scalingFactor: .one,
warmupIterations: 0,
thresholds: .default,
statistics: firstStatistics)

let secondResult = BenchmarkResult(metric: .cpuUser,
timeUnits: .nanoseconds,
scalingFactor: .one,
warmupIterations: 0,
thresholds: .default,
statistics: secondStatistics)

let thirdResult = BenchmarkResult(metric: .cpuUser,
timeUnits: .nanoseconds,
scalingFactor: .one,
warmupIterations: 0,
thresholds: .default,
statistics: thirdStatistics)

var (betterOrEqual, failures) = secondResult.betterResultsOrEqual(than: firstResult,
thresholds: absoluteThresholds)
XCTAssertFalse(betterOrEqual)
XCTAssertFalse(failures.isEmpty, "Failures: \(failures)")

(betterOrEqual, failures) = firstResult.betterResultsOrEqual(than: secondResult,
thresholds: absoluteThresholds)
XCTAssert(betterOrEqual)
XCTAssert(failures.isEmpty)

Benchmark.checkAbsoluteThresholds = true
failures = thirdResult.failsAbsoluteThresholdChecks(thresholds: absoluteThresholdsTwo,
name: "test",
target: "test")
XCTAssert(failures.count > 4)
}

func testBenchmarkResultDescriptions() throws {
let firstStatistics = Statistics()
firstStatistics.add(0)
Expand Down

0 comments on commit 6c80fcf

Please sign in to comment.