To get accurate time measurements on iOS, mach_absolute_time()
should be used. Or CACurrentMediaTime()
, which is based on mach_absolute_time()
. This is documented in this Apple Q&A, and also explained in several StackOverflow answers (e.g. https://stackoverflow.com/a/17986909, https://stackoverflow.com/a/30363702).
When does the value returned by mach_absolute_time()
wrap around? When does the value returned by CACurrentMediaTime()
wrap around? Does this happen in any realistic timespan? The return value of mach_absolute_time()
is of type uint64
, but I'm unsure about how this maps to a real timespan.
The document you reference notes that mach_absolute_time
is CPU dependent, so we can't say how much time must elapse before it wraps. On the simulator, mach_absolute_time
is nanoseconds, so if it's wrapping at UInt64.max
, that translates to 585 years. On my iPhone 7+, it's 24,000,000 mac_absolute_time
per second, which translates to 24 thousand years. Bottom line, the theoretical maximum amount of time captured by mach_absolute_time
will vary based upon CPU, but you won't ever encounter this in any practical application.
For what it's worth, consistent with those various posts you found, the CFAbsoluteTimeGetCurrent
documentation warns that:
Repeated calls to this function do not guarantee monotonically increasing results. The system time may decrease due to synchronization with external time references or due to an explicit user change of the clock.
So, you definitely don't want to use NSDate
/Date
or CFAbsoluteTimeGetCurrent
if you want accurate elapsed times. Neither ensures monotonically increasing values.
In short, when I need that sort of behavior, I generally use CACurrentMediaTime
, because it enjoy the benefits of mach_absolute_time
, but it converts it to seconds for me, which makes it very simple to use. And neither it nor mach_absolute_time
are going to loop in any realistic time period.
For what it is worth, nowadays, we would use ContinuousClock
in Swift. While it doesn’t formally outline its implementation details (probably to afford the flexibility for different implementations in the future and/or to employ different implementations on different platforms), it says:
A clock that measures time that always increments and does not stop incrementing while the system is asleep. …
The frame of reference … may be bound to process launch, machine boot or some other locally defined reference point. This means that the instants are only comparable locally during the execution of a program.
This clock is suitable for high resolution measurements of execution.