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
?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With