1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
|
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import XCTest
import _InstructionCounter
fileprivate var baselineURL: URL {
if let baselineFile = ProcessInfo.processInfo.environment["BASELINE_FILE"] {
return URL(fileURLWithPath: baselineFile)
} else {
return URL(fileURLWithPath: #filePath)
.deletingLastPathComponent()
.appendingPathComponent("baselines.json")
}
}
func measureInstructions(
_ baselineName: StaticString = #function,
block: () -> Void,
file: StaticString = #filePath,
line: UInt = #line
) throws {
let startInstructions = getInstructionsExecuted()
block()
let endInstructions = getInstructionsExecuted()
let numberOfInstructions = endInstructions - startInstructions
let strippedBaselineName = "\(baselineName)".replacingOccurrences(of: "()", with: "")
// Performance testing is only supported on macOS.
// On all other platforms `getInstructionsExecuted` returns 0.
#if os(macOS)
// If the is no data, we just continue the test
guard let data = try? Data(contentsOf: baselineURL) else {
return
}
let jsonDecoder = JSONDecoder()
let baselineMap = try jsonDecoder.decode([String: UInt64].self, from: data)
guard let baseline = baselineMap[strippedBaselineName] else {
XCTFail(
"""
Missing baseline for \(strippedBaselineName)
with number of instructions '\(numberOfInstructions)'
""",
file: file,
line: line
)
return
}
let relativeDeviation = Double(numberOfInstructions) / Double(baseline) - 1
let allowedDeviation = 0.01
XCTAssertTrue(
(-allowedDeviation..<allowedDeviation).contains(relativeDeviation),
"""
Number of instructions '\(numberOfInstructions)' deviated from baseline by \(String(format: "%.4f", relativeDeviation * 100))%.
The maximum allowed deviation for '\(strippedBaselineName)' is \(allowedDeviation * 100)% in either direction.
""",
file: file,
line: line
)
#endif
}
|