How to Time
I was asked three times last week how I find how long an activity takes on the Mac and the iPhone. Here is the most accurate method that I know of:
#import <mach/mach_time.h>
uint64_t start = mach_absolute_time();
// do stuff to be timed
uint64_t end = mach_absolute_time();
uint64_t elapsed = end - start;
mach_timebase_info_data_t info;
if (mach_timebase_info (&info) != KERN_SUCCESS) {
printf ("mach_timebase_info failed\n");
}
uint64_t nanosecs = elapsed * info.numer / info.denom;
uint64_t millisecs = nanosecs / 1000000;
As you use this, remember that the elapsed time for a given function will vary with the load the system is under.
Posted by Aaron Hillegass on November 16th, 2009 under Cocoa.
Comments: 4
Comments
Comment from Steven Degutis
Time: November 16, 2009, 10:00 am
How coincidental that you mention this obscure topic; Mike Ash just posted a blog on his Friday Q&A last week, identifying the problem with using NSDate to find absolute time, and pointing to a solution; here’s the link: http://www.mikeash.com/?page=pyblog/friday-qa-2009-11-13-dangerous-cocoa-calls.html
Comment from Vincent Gable
Time: November 16, 2009, 11:35 am
How would mach_timebase_info() fail, and not return KERN_SUCCESS? I noticed Apple’s sample code ignored the return value: http://developer.apple.com/mac/library/qa/qa2004/qa1398.html
Comment from ryan johnson
Time: December 7, 2009, 9:17 pm
how about something like this (on intel processors):
long long rdtsc_1a,rdtsc_1d,rdtsc_1,rdtsc_2a,rdtsc_2d,rdtsc_2;
double rdtsc_diff;
asm (”rdtsc” : “=a” (rdtsc_1a),”=d” (rdtsc_1d));
//stuff to be timed
asm (”rdtsc” : “=a” (rdtsc_2a),”=d” (rdtsc_2d));
rdtsc_1 = rdtsc_1a | (rdtsc_1d<<32);
rdtsc_2 = rdtsc_2a | (rdtsc_2d<<32);
rdtsc_diff = ((double)rdtsc_2 – (double)rdtsc_1) / [Insert your proc speed];
Comment from Andy Warwick
Time: August 2, 2010, 5:55 pm
So having got the millisecs number, how would you go about printing or logging this in a human-readable format, like ‘0.0034267 seconds’?
Write a comment