Created
October 24, 2016 20:41
-
-
Save kandelvijaya/8095de4ec37f225b7e3fee171d8909fb to your computer and use it in GitHub Desktop.
Precision Timing in iOS/OSX/Swift
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
//: 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
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.