Skip to content

Instantly share code, notes, and snippets.

@Hazer
Created July 4, 2018 23:05
Show Gist options
  • Save Hazer/b6d2bdf78953b6488e47ec32d028c420 to your computer and use it in GitHub Desktop.
Save Hazer/b6d2bdf78953b6488e47ec32d028c420 to your computer and use it in GitHub Desktop.
Swift measure method execution
TimeMeasurer.posixClock("Dependecies configuration") {
self.setupDependencies()
}
// Based on: https://stackoverflow.com/a/51045432/4344807
// and: https://kandelvijaya.com/2016/10/25/precisiontiminginios/
public class TimeMeasurer {
private static func measure<N: Numeric>(measurer: Measurer<N>, tag: String, closure: (()->())?) {
let time = measurer.measure(closure: closure)
print("\(tag) measured time: \(time)")
}
public static func processInfo() -> Measurer<TimeInterval> {
return StrictSimpleMeasurer<TimeInterval> { ProcessInfo.processInfo.systemUptime }
}
public static func posixClock() -> Measurer<Double> {
return StrictSimpleMeasurer<Double>(startClosure: { Double(clock()) }) { (Double(clock()) - $0 ) / Double(CLOCKS_PER_SEC) }
}
public static func date() -> Measurer<TimeInterval> {
return StrictSimpleMeasurer<TimeInterval> { Date().timeIntervalSince1970 }
}
public static func matchAbsTime(useNanos: Bool = false) -> Measurer<TimeInterval> {
var info = mach_timebase_info()
guard mach_timebase_info(&info) == KERN_SUCCESS else { return StrictSimpleMeasurer<TimeInterval>(startClosure: {-1}, endClosure: {_ in -1}) }
return AbstractMeasurer<TimeInterval>(calcClosure: { clos in
let currentTime = mach_absolute_time()
clos?()
let elapsed = mach_absolute_time() - currentTime
let nanos = elapsed * UInt64(info.numer) / UInt64(info.denom)
if useNanos {
return TimeInterval(nanos)
}
return TimeInterval(nanos) / TimeInterval(NSEC_PER_SEC)
})
}
public static func matchAbsTime(_ tag: String, useNanos: Bool = false, closure: (()->())?) {
return measure(measurer: matchAbsTime(useNanos: useNanos), tag: tag, closure: closure)
}
public static func date(_ tag: String, closure: (()->())?) {
measure(measurer: date(), tag: tag, closure: closure)
}
public static func processInfo(_ tag: String, closure: (()->())?) {
measure(measurer: processInfo(), tag: tag, closure: closure)
}
public static func posixClock(_ tag: String, closure: (()->())?) {
measure(measurer: posixClock(), tag: tag, closure: closure)
}
class AbstractMeasurer<T: Numeric>: Measurer<T> {
private let calcClosure: ((()->())?) -> (T)
init(calcClosure: @escaping ((()->())?) -> (T)) {
self.calcClosure = calcClosure
}
public override func measure(closure: (()->())?) -> T {
return calcClosure(closure)
}
}
}
public class Measurer<T: Numeric> {
internal init() {
}
open func measure(closure: (()->())?) -> T {
closure?()
return -1
}
}
public class StrictSimpleMeasurer<T: Numeric>: Measurer<T> {
private let startClosure: ()->(T)
private let endClosure: (_ beginningTime: T)->(T)
init (startClosure: @escaping ()->(T), endClosure: @escaping (_ beginningTime: T)->(T)) {
self.startClosure = startClosure
self.endClosure = endClosure
}
init (getCurrentTimeClosure: @escaping ()->(T)) {
startClosure = getCurrentTimeClosure
endClosure = { beginningTime in
return getCurrentTimeClosure() - beginningTime
}
}
public override func measure(closure: (()->())?) -> T {
let value = startClosure()
closure?()
return endClosure(value)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment