Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-C optimization

Are there standard optimization tricks for Objective-C to make for faster execution along the lines of "inlining" frequent methods as in C++ or the "g++ -fast" tag?

Edit: Does anyone have a short example using SEL and IMP when theMethod has two (or more) integers for input?

like image 816
SK9 Avatar asked Mar 28 '10 23:03

SK9


1 Answers

Here's a small optimisation that may not really be worth the time to implement, and one that I never use personally, but I guess still good to know about. Rather than repeatedly sending the same message to the same object over and over, you can bypass repeated method dispatch by directly using the method implementation. For example, instead of:

for (int i = 0; i < 100000000; i++)
    [someObject messageWithInt:i];

You could try:

SEL theSelector = @selector(messageWithInt:);
IMP theMethod = [someObject methodForSelector:theSelector];

for (int i = 0; i < 100000000; i++)
    theMethod (someObject, theSelector, i);

This means that the method lookup is only done once and you can invoke the method directly through the returned IMP value. All Objective-C method implementations take at least two arguments, the first argument is the receiving object of type id, which becomes self within the method implementation, and the second argument is the selector [of type SEL] that was used to determine the method implementation, and becomes _cmd in the method implementation.

This approach can quickly turn sour if you don't use the correct “function definition” (I can't remember the proper term). IMP is a typedef for a function that returns void* and takes (id,SEL,...) as arguments. This can make it troublesome to use if the method actually returns something else like float. To help with this matter, you can cast the return value of -methodForSelector:, like this:

typedef float (*MyMethodIMP)(id,SEL,int);

SEL theSel = @selector(messageWithInt:);
MyMethodIMP theMethod = (MyMethodIMP)[someObject methodForSelector:theSel];
float result = 0.0;

for (int i = 0; i < 100000000; i++)
    result += theMethod (someObject, theSel, i);

With some care, you can save the theMethod and you may be able to use it for all instances of a particular class, not just one instance, but tread carefully.

like image 95
dreamlax Avatar answered Nov 15 '22 20:11

dreamlax