Timing Objective-C code

benchmarking, objective-c, performance

Solution

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.

Problem

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`?

Original source