开发者

Objective-C optimization

开发者 https://www.devze.com 2022-12-25 11:47 出处:网络
Are there standard optimization tricks for Objective-C to make for faster execution along the lines of \"inlining\" frequ开发者_运维问答ent methods as in C++ or the \"g++ -fast\" tag?

Are there standard optimization tricks for Objective-C to make for faster execution along the lines of "inlining" frequ开发者_运维问答ent 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?


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.


Optimization is best handled by the compiler. Macs use GCC, so the standard optimization GCC flag (-Olevel) should work. In XCode, you can set the optimization level in the project settings. If you're not using GCC, check you compiler documentation for how to enable optimization.

Update: XCode 4 uses the LLVM backend by default. Both the GCC and clang frontends use "-On" optimization flags. For GCC, n is an integer from 0 through 3, or "s" or (Apple only) "z". For clang, n is an integer from 0 through 4, or "s".

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号