-
-
Save abargh/fd07cd9e249dc198a83a25ebfdef99b6 to your computer and use it in GitHub Desktop.
A tool to measure code performance in Swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Created by Florent Pillet on 14/11/16. | |
// Copyright (c) 2016 Florent Pillet. All rights reserved. | |
// | |
import Foundation | |
/* | |
* A utility struct that helps mesure the performance of sections of code. Only uses Foundation | |
* (we could also use QuartzCore's CACurrentMediaTime() for similar precision) | |
* | |
* Usage: | |
* | |
* MeasurePerf("this code took: ") { | |
* // code to execute here | |
* } | |
* | |
* Will output: | |
* this code took 0.12143673s | |
* | |
* You can also provide a logging closure for customized logging, or use the default constructor | |
* and use the time yourself: | |
* | |
* let perf = MeasurePerf { | |
* // code to measure here | |
* } | |
* | |
*/ | |
public struct MeasurePerf { | |
static let NANOSECONDS_IN_SECOND : UInt64 = 1_000_000_000 | |
static let NANOSECONDS_IN_MILLISECOND : UInt64 = 1_000_000 | |
static let NANOSECONDS_IN_MICROSECOND : UInt64 = 1000 | |
private let startTime = mach_absolute_time() | |
private(set) var doubleSeconds : Double = 0.0 // a single timing result | |
private(set) var seconds : UInt64 = 0 // breakdown timing results | |
private(set) var milliseconds : UInt64 = 0 | |
private(set) var microseconds : UInt64 = 0 | |
private(set) var nanoseconds : UInt64 = 0 | |
init(code: () throws -> Void) rethrows { | |
defer { computeTime() } | |
try code() | |
} | |
@discardableResult | |
init(_ message: String, code: () throws -> Void) rethrows { | |
defer { | |
computeTime() | |
print("\(message) \(self.doubleSeconds)s") | |
} | |
try code() | |
} | |
@discardableResult | |
init(_ loggingClosure: (UInt64, UInt64, UInt64, UInt64) -> Void, code: () throws -> Void) rethrows { | |
defer { | |
computeTime() | |
loggingClosure(self.seconds, self.milliseconds, self.microseconds, self.nanoseconds) | |
} | |
try code() | |
} | |
@discardableResult | |
init(_ loggingClosure: (Double) -> Void, code: () throws -> Void) rethrows { | |
defer { | |
computeTime() | |
loggingClosure(self.doubleSeconds) | |
} | |
try code() | |
} | |
private mutating func computeTime() { | |
let endTime = mach_absolute_time() | |
let elapsed = endTime - startTime | |
var timeBase = mach_timebase_info_data_t() | |
mach_timebase_info(&timeBase) | |
var nanos = elapsed * UInt64(timeBase.numer) / UInt64(timeBase.denom); | |
seconds = nanos / MeasurePerf.NANOSECONDS_IN_SECOND | |
nanos = nanos - (seconds * MeasurePerf.NANOSECONDS_IN_SECOND) | |
milliseconds = nanos / MeasurePerf.NANOSECONDS_IN_MILLISECOND | |
nanos = nanos - (milliseconds * MeasurePerf.NANOSECONDS_IN_MILLISECOND) | |
microseconds = nanos / MeasurePerf.NANOSECONDS_IN_MICROSECOND | |
nanoseconds = nanos - (microseconds * MeasurePerf.NANOSECONDS_IN_MICROSECOND) | |
doubleSeconds = Double(nanos) / Double(MeasurePerf.NANOSECONDS_IN_SECOND) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment