Objective-C 优化

10

有没有适用于Objective-C的标准优化技巧,使得执行更快,类似于C++中经常使用的"内联"方法或"g++ -fast"标记?

编辑:有人可以提供一个使用SEL和IMP的简短示例吗?theMethod具有两个(或多个)整数作为输入?


这个主题在这里有详细的讨论:http://www.mulle-kybernetik.com/artikel/Optimization/ - codewarrior
1
在像Cocoa这样的高级框架中,大多数像这样的小优化都是浪费时间的(除了更改编译器设置),因为许多基础类已经被大量优化。只有在分析显示某些内容需要额外花费大量时间时,才应进行优化。 - shosti
2个回答

13

这里有一个小的优化建议,可能不值得花时间去实现,而且我个人从未使用过,但我觉得还是很好知道的。与其反复向同一个对象发送相同的消息,你可以通过直接使用方法实现来绕过重复的方法调用。例如,不要使用:

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

您可以尝试:

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

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

这意味着方法查找只进行一次,您可以通过返回的IMP值直接调用方法。所有Objective-C方法实现至少需要两个参数,第一个参数是类型为id的接收对象,在方法实现中变为self,第二个参数是用于确定方法实现的选择器[类型为SEL],在方法实现中变为_cmd

如果您没有使用正确的“函数定义”(我记不起正式术语了),这种方法可能很快就会变得糟糕。 IMP是一个typedef,表示返回void*并将(id、SEL、...)作为参数的函数。如果方法实际上返回其他东西,比如float,这可能会使使用起来麻烦。为了解决这个问题,您可以像这样对-methodForSelector:的返回值进行转换:

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);

小心操作,您可以保存theMethod,并且您可能能够将其用于特定类的所有实例,而不仅仅是一个实例,但一定要小心谨慎。


6
和大部分性能优化工具一样,你可以在你的代码上运行Instruments来查看瓶颈所在。上面列出的这些内容非常棒...如果你需要它们的话。如果不需要,只会使得代码难以阅读。 - nall
2
@nall:绝对没错。我进行了一些基本的基准测试,在像上面那样的紧密循环中,绕过调度大约可以减少一半的执行时间(theMethod 进行了一些基本的数学计算)。如果在 objc_msgSend(或者现在叫什么方法)中花费了很多时间,那么绕过调度可能是一个选项,否则,就像你说的那样,这将更多地是一种混淆而不是优化。 - dreamlax
这是一个非常有趣的优化,但是制作一个 C 函数会不会更容易,而不是从方法中获取 IMP? - shosti
@eman:如果你能够做到,当然可以;但是如果你在使用一个闭源框架中的对象,则可能无法这样做。 - dreamlax

9
优化最好由编译器处理。Macs使用GCC,因此标准优化GCC标志(-Olevel)应该有效。在XCode中,您可以在项目设置中设置优化级别。如果您没有使用GCC,请查看您的编译器文档以了解如何启用优化。
更新:XCode 4默认使用LLVM后端。GCC和clang前端都使用“-On”优化标志。对于GCC,n是从0到3的整数,或者是“s”或(仅适用于苹果公司的)“z”。对于clang,n是从0到4的整数,或者是“s”。

非常感谢大家提供的建议和时间!如果您愿意,能否举一个例子,当theMethod接受两个或更多整数作为输入时,使用SEL和IMP。 - Ken
@SpecialK:一个简短的例子是关于什么的?你是想评论dreamlax的回答吗? - outis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接