Question

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?

Was it helpful?

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top