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
|
// Taken from swift-collections-benchmark
public struct Timer {
internal var _expectNested: Bool? = nil
public var elapsedTime: Time? = nil {
didSet {
precondition(_expectNested != false,
"Inconsistent timer use: Unexpected call to Timer.elapsedTime setter")
}
}
public init() {}
internal init(_expectNested: Bool?) {
self._expectNested = _expectNested
}
internal static func _measureFirst(
_ body: (inout Timer) -> Void
) -> (elapsedTime: Time, hasNestedMeasurement: Bool) {
var timer = Timer(_expectNested: nil)
let start = Tick.now
body(&timer)
let end = Tick.now
let elapsed = timer.elapsedTime ?? end.elapsedTime(since: start)
return (elapsedTime: elapsed._orIfZero(Tick.resolution),
hasNestedMeasurement: timer.elapsedTime != nil)
}
internal static func _nestedMeasure(_ body: (inout Timer) -> Void) -> Time {
var timer = Timer(_expectNested: true)
body(&timer)
guard let elapsed = timer.elapsedTime else {
fatalError("Inconsistent timer use: Expected call to Timer.measure")
}
return elapsed._orIfZero(Tick.resolution)
}
internal static func _iteratingMeasure(
iterations: Int,
_ body: (inout Timer) -> Void
) -> Time {
precondition(iterations > 0)
var timer = Timer(_expectNested: false)
let start = Tick.now
for _ in 0 ..< iterations {
body(&timer)
}
let end = Tick.now
let elapsed = end.elapsedTime(since: start)._orIfZero(Tick.resolution)
return Time(elapsed.seconds / Double(iterations))
}
@inline(never)
public mutating func measure(_ body: () -> Void) {
precondition(_expectNested != false,
"Inconsistent timer use: Unexpected call to Timer.measure")
let start = Tick.now
body()
let end = Tick.now
elapsedTime = end.elapsedTime(since: start)
_expectNested = false
}
}
|