Measuring time in microseconds on iOS - ios

I’m trying to get system time in microseconds to measure time between two events. I need to measure at minimum to 1/10th of a millisecond.
I know of NSDate and CFAbsoluteTimeGetCurrent, but both only do milliseconds. Does anyone know of a way I can do this?

CFAbsoluteTimeGetCurrent calls gettimeofday, which has microsecond resolution.
NSDate is simply a wrapper around a CFAbsoluteTime, so it also has microsecond resolution.
Why do you think they only have millisecond resolution?

See mach_absolute_time. It has granularity down to nanoseconds.
http://shiftedbits.org/2008/10/01/mach_absolute_time-on-the-iphone/

Related

CAPL function for printing milliseconds?

it is complex to understand the canlogs without milliseconds, is there any function that prints milliseconds in write window. i've already tried with "getLocalTimeString()" function but this will print only time till seconds only.
Try using the funtion timeNowNS(); returning a float variable of the simulation time in nanoseconds. Alternatively use timeNowInt64();. Multiply the returned value with factor to gain seconds/milli seconds as you see fit.
timeNowNS() will return simulation time in nanoseconds whereas getLocalTime()/getLocalTimeString() will return system time.
appending both will make no sense as it won't be accurate

(When) Does CACurrentMediaTime/mach_system_time wrap around on iOS?

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.

iOS prevent date/time update?

a relatively simple question that I've not been able to find a clear answer to. My app is more complex, but answering this question will suffice.
Suppose you're writing a stopwatch app. When the user taps "start", the app stores the current date and time in startTime:
startTime = [NSDate date];
When the user tapes "stop", the app stores the current date and time in stopTime:
stopTime = [NSDate date];
The duration is calculated by:
duration = [stopTime timeIntervalSinceDate:startTime];
and is displayed with something like:
[durationLabel setText:[NSString stringWithFormat:#"%1.2f", duration]];
The typical durations that my app is timing range from 2 to 50 seconds. I need accuracy to 1/100th of a second (e.g. 2.86 seconds).
I'm assuming that there is some protocol that iOS devices use to keep their clocks accurate (cellular or NTP sources?). My concern is that between starting and stopping the stopwatch, the clock on the iOS device is updated which can result in a shift of the current date/time either ahead or back. If this were to happen, the duration calculated would be inaccurate.
I've seen a few posts relating to timing methods for purposes of improving code efficiency. Some suggest using mach_time.h functions, which I'm not familiar with. It's not obvious to me which is the best approach to use.
Is it possible to disable iOS from updating the date & time? Is mach_absolute_time() unaffected by iOS clock updates?
Many thanks!
Tim
You are correct in thinking that CFAbsoluteTime and its derivatives (NSDate dateand so on) are potentially skewed by network updates on 'real' time. Add that to the fact that NSTimer has an accuracy of 50-100ms and you have a timer that is not suited to the most critical of time-sensitive operations.
The answer to this problem seems to be CACurrentMediaTime.
It is a member of the Core Animation group, but there shouldn't be any problem integrating it into non-animation based applications.
CACurrentMediaTime is a wrapper of mach_absolute_time() and makes sense of the "mach absolute time unit," which from my understanding is no fun to tinker with. mach_absolute_time() is calculated by running a non-network synced timer since the device was last booted.
There is relatively little information on CACurrentMediaTime but here are some sources and further reading:
Apple's sparse documentation of CACurrentMediaTime
Stack Overflow - NSTimer vs CACurrentMediaTime()
http://bendodsonapps.com/weblog/2013/01/29/ca-current-media-time/
http://blog.spacemanlabs.com/2011/09/all-in-the-timing-keeping-track-of-time-passed-on-ios/
http://forum.sparrow-framework.org/topic/accurate-timer
Note: If you do use CACurrentMediaTime, make sure you include and link the QuartzCore.framework
Check out this here. I would say forget about the current time check and use a precision timer since it won't rely on the current time but instead uses an interval.

Timing how long a function takes

I've seen Q/A here about timing function duration in other languages but didn't find anything in Objective-C. If there is one, post the link and I will delete this question
I want to measure the time it takes for some functions to run. I've cobbled together the bits of code below but I wonder if there is a more compact or portable way to do this.
CFTimeInterval startTime = CFAbsoluteTimeGetCurrent();
// do some work
CFTimeInterval difference = CFAbsoluteTimeGetCurrent() - startTime;
printf("elapsed: %f\n", difference)
If you want to precisely time very short timespans there are two additional timing facilities with very low overhead that come to my mind:
mach_absolute_time with nanosecond resolution
__builtin_readcyclecounter: a clang builtin function to read a low-latency, high-accuracy clock.
No,This is the best way using CFAbsoluteTimeGetCurrent();
its Absolute time is measured in seconds relative to the absolute reference date of Jan 1 2001 00:00:00 GMT

How to giva a time accurate timer in Fire Monkey?

I have to display a timer in 10th second for a sport competition. I have do this using the OnTimer event of a TTimer. the interval is set to 100. My routine display the current min:sec.10th (ex.: 02:45.7 ) correctly but it seem that my timer loose about 4 second at each minutes if I comp. to normal clock.
There is a better way to get a time accuracy timer in Delphi XE2 (or XE3) ?
You can use a timer to display the current value of the clock, but use a different approach to calculate the elapsed time.
You have to know that Windows timers are not time accurate, and even if you set it to elapse every 100 milliseconds, it can take more to fire the OnTimer event and even it can miss some intervals if for some reason elapses two or more times before your application process it.
You can, for example, use the system high-resolution performance counter to track times with nano-second accuracy.
You can also use the Delphi TStopwatch class, which encapsulates the system calls and falls back to other method (GetTickCount) if the high resolution performance counter is not available in your machine.
Take also a look at the How to Accurately Measure Elapsed Time Using High-Resolution Performance Counter delphi.about.com article.

Resources