Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Timing Objective-C code

I would like to add some automated performance test to my Objective-C application. (This is a game, so that I would like to see the current performance of key parts of the engine by simply running a set of tests.) To do this I want to write some timing support routine, something like this:

- (void) benchmarkSelector: (SEL) msg onObject: (id) target
{
    // run the selector thousands of times, print detailed stats
}

The problem is that I am interested in milliseconds and I am afraid that calling performSelector in the benchmarking code would skew the results quite a bit. How would you go around this? Should I go down to objc_msgSend?

like image 536
zoul Avatar asked Jun 23 '09 06:06

zoul


1 Answers

Use methodForSelector:, which returns a function pointer to the actual implementation, like so:

IMP methodImp = [target methodForSelector:msg];
for (int i=0; i<1000; ++i) {
    NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate];
    methodImp(target, msg);

    NSTimeInterval duration = [NSDate timeIntervalSinceReferenceDate] - start;
    // Do something with duration
}

Note that this strategy is useful for measuring the actual runtime of a method, but if you're going to be calling it with standard Objective-C message-passing syntax, then it might be just as relevant to include the message-passing overhead in your measurements.

Also, note that if the method actually takes any other parameters, you should cast the result of methodForSelector: to a function pointer with the appropriate parameters, to avoid unexpected conversion of floats to doubles, etc. See the NSObject Class Reference for more information and examples.

like image 99
BJ Homer Avatar answered Sep 18 '22 00:09

BJ Homer