Saturday, July 21, 2012

High resolution timing in Cocoa

Note: This blog is deprecated. @synthesize zach has moved to a new home, at zpasternack.org. This blog entry can be found on the new blog here. Please update your links.

For profiling app performance, it's necessary to accurately time your code. The best way to do this is to use mach_absolute_time. In conjunction with mach_timebase_info, you can get extremely high resolution timing to ease performance benchmarking.

I've wrapped this functionality up in a little class to make it super easy to use.

// MachTimer.h
#include <mach/mach_time.h>

@interface MachTimer : NSObject
{
    uint64_t timeZero;
}

+ (id) timer;

- (void) start;
- (uint64_t) elapsed;
- (float) elapsedSeconds;
@end
// MachTimer.m
#import "MachTimer.h"

static mach_timebase_info_data_t timeBase;

@implementation MachTimer

+ (void) initialize
{
    (void) mach_timebase_info( &timeBase );
}

+ (id) timer
{
#if( __has_feature( objc_arc ) )
    return [[[self class] alloc] init];
#else
    return [[[[self class] alloc] init] autorelease];
#endif
}

- (id) init
{
    if( (self = [super init]) ) {
        timeZero = mach_absolute_time();
    }
    return self;
}

- (void) start
{
    timeZero = mach_absolute_time();
}

- (uint64_t) elapsed
{
    return mach_absolute_time() - timeZero;
}

- (float) elapsedSeconds
{
    return ((float)(mach_absolute_time() - timeZero)) 
        * ((float)timeBase.numer) / ((float)timeBase.denom) / 1000000000.0f;
}

@end
You'd use it like this:
MachTimer* aTimer = [MachTimer timer];
[self performSomeOperation];
NSLog( @"performSomeOperation took %f seconds", [aTimer elapsedSeconds] );
I've used this code for iOS and Mac OS apps, and it works great.

No comments:

Post a Comment