Precision Timing in iOS/OSX/Swift
//: Playground - noun: a place where code can play | |
import UIKit | |
//Most precise time keeper | |
// for more information on the benchmarks go to www.kandelvijaya.com | |
func timeBlockWithMach(_ block: () -> Void) -> TimeInterval { | |
var info = mach_timebase_info() | |
guard mach_timebase_info(&info) == KERN_SUCCESS else { return -1 } | |
let start = mach_absolute_time() | |
block() | |
let end = mach_absolute_time() | |
let elapsed = end - start | |
let nanos = elapsed * UInt64(info.numer) / UInt64(info.denom) | |
return TimeInterval(nanos) / TimeInterval(NSEC_PER_SEC) | |
} | |
func test() { | |
let rtDate = timeBlockWithMach{ | |
NSDate().timeIntervalSince1970 | |
} | |
let rtMedia = timeBlockWithMach { | |
CACurrentMediaTime() | |
} | |
let rtAbsolute = timeBlockWithMach { | |
CFAbsoluteTimeGetCurrent() | |
} | |
var time = timeval() | |
let rtTimeOfDay = timeBlockWithMach { | |
gettimeofday(&time, nil) | |
} | |
let rtTimeWithMach = timeBlockWithMach { | |
mach_absolute_time() | |
} | |
let rtTimeWithProcessInfo = timeBlockWithMach { | |
ProcessInfo.processInfo.systemUptime | |
} | |
} | |
test() | |
// MARK: - Other timing functions | |
func timeBlockWithDateTime(_ block: () -> Void) -> TimeInterval { | |
let start = NSDate().timeIntervalSince1970 | |
block() | |
let end = NSDate().timeIntervalSince1970 | |
return end - start | |
} | |
func timeBlockWithCAMediaTiming(_ block: () -> Void) -> TimeInterval { | |
let start = CACurrentMediaTime() | |
block() | |
let end = CACurrentMediaTime() | |
return end - start | |
} | |
func timeBlockWithCFTime(_ block: () -> Void) -> TimeInterval { | |
let start = CFAbsoluteTimeGetCurrent() | |
block() | |
let end = CFAbsoluteTimeGetCurrent() | |
return end - start | |
} | |
func timeBlockWithGetTimeOfDay(_ block: () -> Void) -> TimeInterval { | |
var start = timeval() | |
gettimeofday(&start, nil) | |
block() | |
var end = timeval() | |
gettimeofday(&end, nil) | |
return Double(start.tv_usec - end.tv_usec) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
When benchmarking using the above functions, its always a good idea to run the code/function/block in a loop of several 100 times and average the running time to get a proximate time. Running time of a code is different at different times. However, the ratio of running time for 2 different code is equivalent.