Rich @siegel asked on twitter:
How expensive is it to call a block, versus a method, versus a function? Asking for a friend.
— Rich Siegel (@siegel) March 14, 2013
and @danielpunkass pointed to a @mikeash blog post with some tests:
@rentzsch @siegel I was reminded by @mikeash of this old gem: mikeash.com/pyblog/perform… Maybe just needs an update for blocks…
— Daniel Jalkut (@danielpunkass) March 14, 2013
I was curious about this so I added that test and a test of the new @autoreleasepool {}
construct. The modified code is here (@mikeash feel free to grab it and use it on your site) and the results of running this on my older MacBook Air 1.8GHz Core i7 with 4GB 1333MHz DDR3 RAM and SSD (other apps running in the background) are as follows:
Name | Iterations | Total time (sec) | Time per (ns) |
IMP-cached message send | 1000000000 | 0.2 | 0.2 |
C++ virtual method call | 1000000000 | 0.4 | 0.4 |
Block invocation | 1000000000 | 0.5 | 0.5 |
Integer division | 1000000000 | 2.3 | 2.3 |
Objective-C message send | 1000000000 | 2.7 | 2.7 |
16 byte memcpy | 100000000 | 0.4 | 4.4 |
Floating-point division | 100000000 | 0.6 | 6.0 |
Float division with int conversion | 100000000 | 0.6 | 6.3 |
New Autorelease construct | 10000000 | 0.2 | 17.1 |
NSAutoreleasePool alloc/init/release | 10000000 | 0.6 | 63.5 |
16 byte malloc/free | 100000000 | 6.5 | 64.7 |
NSInvocation message send | 10000000 | 0.9 | 91.3 |
NSObject alloc/init/release | 10000000 | 1.6 | 165.0 |
16MB malloc/free | 100000 | 0.1 | 880.0 |
NSButtonCell creation | 1000000 | 3.2 | 3201.7 |
Read 16-byte file | 100000 | 0.8 | 8250.8 |
pthread create/join | 10000 | 0.2 | 23009.4 |
Zero-second delayed perform | 100000 | 2.8 | 28038.3 |
NSButtonCell draw | 100000 | 4.7 | 47448.6 |
1MB memcpy | 10000 | 0.8 | 78902.2 |
Write 16-byte file | 10000 | 2.1 | 209280.7 |
Write 16-byte file (atomic) | 10000 | 3.9 | 392459.6 |
Read 16MB file | 100 | 0.8 | 8050127.5 |
NSTask process spawn | 1000 | 67.3 | 67305116.9 |
Write 16MB file (atomic) | 30 | 2.1 | 70342873.5 |
Write 16MB file | 30 | 2.2 | 72666382.1 |
Built it with:
cc -v -lstdc++ -framework Cocoa perf.mm
and the dev tools are:
Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
Target: x86_64-apple-darwin12.2.0
Thread model: posix
Xcode 4.6 basically.
If Mike reads this: feel free to grab any of this you want and copy it to your site. Just put it here because that was easiest.
Not sure my tests are exactly right so feel free to make suggestions etc. One thing I didn’t test but might add another test for is how handling local variables used in the block impacts things; likewise local __block variables in the block, but the whole point of this test suite seemed to be keeping things as simple as possible so I stuck with that.
UPDATE:
@schwa asked about iOS and since I had the day off I went ahead and did those as well, though I had to remove some tests I didn’t feel like fixing for iOS (zero delay perform selector messes with the RunLoop which caused crashes, no NSButton class, NSTask (?), and the file I/O tests weren’t going to work as is). Started with the single view iOS Application Xcode template and added a text view to jam the results into. This was run on an iPhone 5 running iOS 6.0.2:
Name | Iterations | Total time (sec) | Time per (ns) |
C++ virtual method call | 1000000000 | 0.8 | 0.8 |
Block invocation | 1000000000 | 2.8 | 2.8 |
IMP-cached message send | 1000000000 | 4.6 | 4.6 |
Objective-C message send | 1000000000 | 14.7 | 14.7 |
Float division with int conversion | 100000000 | 1.8 | 17.8 |
Floating-point division | 100000000 | 1.8 | 17.8 |
Integer division | 1000000000 | 21.6 | 21.6 |
16 byte memcpy | 100000000 | 6.1 | 61.0 |
New Autorelease construct | 10000000 | 0.8 | 83.4 |
16 byte malloc/free | 100000000 | 46.8 | 467.5 |
NSAutoreleasePool alloc/init/release | 10000000 | 5.2 | 519.2 |
NSObject alloc/init/release | 10000000 | 12.6 | 1259.0 |
NSInvocation message send | 10000000 | 13.5 | 1346.3 |
16MB malloc/free | 100000 | 1.5 | 15374.9 |
pthread create/join | 10000 | 1.2 | 116415.9 |
1MB memcpy | 10000 | 3.9 | 394341.5 |