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;

@end


// 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];
#else
    return [[[[self class] alloc] init] autorelease];
#endif
}

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

    [aTimer start];
    block();
    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;
}

@end

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.