NSDate
Others have warned that NSDate can shimmy a bit when used for micro-benchmarking. But for casual use it works just fine.
NSDate *start = [NSDate date];
// …
NSTimeInterval timeInterval = [start timeIntervalSinceNow];
NSLog(@"elapsedTime after Check call: %f" , timeInterval );
There may well be better ways, but this does work. For example, I timed a method call on an iPod touch 5th generation where it consistently took 0.21 to 0.25 seconds over several runs. Switching to an iPad Air the same method consistently took 0.11 to 0.13 seconds over several runs. Granted, that is a 10-20% variance approximately on both devices. But the casual observing, this may suffice for your needs. Just be sure to make multiple runs of your test.
Example run with Receigen code
Example run, executing some code that harnesses source code generated by the Receigen Mac app for App Receipt Validation. NSDate seems to be tracking microseconds well.
I am not including source code, but you can get the main idea with this description of the sequence of events.
- A block of code is defined and populated. No business logic executed, just creating the Objective-C block (a closure).
- My implementation of
SKRequestDelegate
is instantiated. No real code, just some logging via NSLog.
- The generated Receigen code is executed. This is a bunch of obfuscated C code that does some decryption work by invoking OpenSSL to parse through Apple’s App Receipt.
- After the decrypting and parsing, Receigen reports its results by invoking our block that we defined up top. This block is called once for each of our three In-App Purchase products.
- One final capture of elapsed time, after the Receigen-generated code returns.
You can see below that the block definition is a mere 22 microseconds. The instantiation of of our SKRequestDelegate
is much more, around 1,500 microseconds. The Receigen decryption & parsing takes the vast majority of time, about 0.1 seconds to execute. Then around a hundred microseconds to report its findings by invoking the block each of three times.
2016-09-03 17:13:57.883 XXApp[231:7509] elapsedTime after declare & populate a block: -0.000022
2016-09-03 17:13:57.884 XXApp[231:7509] elapsedTime after instantiating implementation of SKRequestDelegate
: -0.001579
2016-09-03 17:13:57.995 XXApp[231:7509] elapsedTime after Receigen code called the block: -0.112392
2016-09-03 17:13:57.995 XXApp[231:7509] elapsedTime after Receigen code called the block: -0.112482
2016-09-03 17:13:57.995 XXApp[231:7509] elapsedTime after Receigen code called the block: -0.112556
2016-09-03 17:13:57.997 XXApp[231:7509] elapsedTime after Receigen code done: -0.115133
After running this several times with consistent results, I conclude that NSDate is indeed useful for casual benchmarking in the millisecond-microsecond range.