High resolution timing in Cocoa, revisited

A while back I wrote about high resolution timing in Cocoa. It's been a while, and I've updated it a bit – adding ARC support, adding a call to time a block, and removing some stuff that wasn't needed. Hopefullly you find it useful.

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

@interface MachTimer : NSObject

+ (instancetype) timer;
+ (NSTimeInterval) timeForBlock:(void (^)(void))block;

- (void) start;
- (NSTimeInterval) elapsedSeconds;


// MachTimer.m
#import "MachTimer.h"

static mach_timebase_info_data_t timeBase;

@implementation MachTimer
    uint64_t timeZero;

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

- (instancetype) init
    self = [super init];
    if( self ) {
        [self start];
    return self;

+ (instancetype) timer
#if( __has_feature( objc_arc ) )
    return [[[self class] alloc] init];
    return [[[[self class] alloc] init] autorelease];

+ (NSTimeInterval) timeForBlock:(void (^)(void))block
    MachTimer* aTimer = [self timer];

    [aTimer start];
    return [aTimer elapsedSeconds];

- (void) start
    timeZero = mach_absolute_time();

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


You might use it like this:

MachTimer* aTimer = [MachTimer timer];
[self doSomeLengthyOperation];
NSLog( @"Lengthy operation took %f seconds", [aTimer elapsedSeconds] );

Or, with the new block call:

NSTimeInterval theTime = [MachTimer timeForBlock:^{
    // Do some lengthy operation.
NSLog( @"Lengthy operation took %f seconds", theTime );

Credit where credit is due

I originally found the basis for this code on the Apple message boards, here. I dunno who wrote that, but thanks, dude. If you're that guy, let me know, and I'll be happy to give you attribution. Since writing this, I've discovered Waffle Software has a similar thing, which has some additional functionality; check that out if you're interested.

If you want to follow me, I'm @zpasternack on Twitter and on app.net.