Created
July 4, 2018 23:05
-
-
Save Hazer/b6d2bdf78953b6488e47ec32d028c420 to your computer and use it in GitHub Desktop.
Swift measure method execution
This file contains 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
TimeMeasurer.posixClock("Dependecies configuration") { | |
self.setupDependencies() | |
} |
This file contains 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
// 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