LLVM是否将Objective-C方法转换为内联函数?

时间:2011-11-19 13:56:33

标签: objective-c performance llvm inline-functions

  1. LLVM是否会在可能的情况下自动将Objective-C方法转换为内联函数?

    (即,是否能够为一段代码创建一个Objective-C方法,否则你可以粘贴内联?)

  2. 如果LLVM没有执行此优化,为什么不呢?如果是,(a)是否有必须为此设置的某些构建设置? (b)如何判断是否内联Objective-C方法?

3 个答案:

答案 0 :(得分:12)

不,因为在Obj-C运行时的上下文中无法知道是否可以执行这些优化。要记住的是Obj-C方法是由消息发送调用的,这些消息不仅仅来自[myObject doSomething]语法。

考虑[obj performSelector:NSSelectorFromString(@"hello")]这可能发生的事实意味着不可能内联任何方法。

当类接收到消息时,也会发生一系列事件,这些事件可以重新路由,甚至更改正在发送的消息。这在邮件发送的下方透明地发生。

答案 1 :(得分:9)

没有。 Objective-C的一个基本特征是消息调度(记住在Obj-C中你发送消息,你没有调用方法)在运行时动态发生,而不是在编译时。

因此,Obj-C中的消息调度总是比纯函数调用慢一点(即使函数没有内联)。

答案 2 :(得分:9)

让我们暂时假设编译器内联一个方法:

@implementation AwesomeClass 

- (void)doFoo OBJC_INLINE { // or some way to indicate "this is an inline method"
  NSLog(@"doing foo!");
}

- (void)doBar {
  [self doAwesomeStuff];
  [self doFoo];
}

@end

以便-doBar基本上成为:

- (void)doBar {
  [self doAwesomeStuff];
  {
    NSLog(@"doing foo!");
  }
}

太棒了,好像它会更快,对吧?我们通过不调用objc_msgSend来保存自己的十几条指令。因此,您打包并将其作为.a文件在线发布。

NSCleverCoder出现并说“但我希望doFoo再做一点”,所以他做了:

@interface SuperAwesomeClass : AwesomeClass @end
@implementation SuperAwesomeClass
- (void)doFoo {
  NSLog(@"doing more foo!");
  [super doFoo];
}
@end

当他试图运行它时,它永远不会被调用,因为AwesomeClass从未实际调用-doFoo方法。

“但是,”你说,“这是一个人为的例子!”

不,不是。在Objective-C中,在开发或执行应用程序的任何时候执行此操作是完全合法的。我可以在编写代码时执行此操作。哎呀,我甚至可以在运行时使用objc_allocateClassPairclass_addMethod来动态创建子类并添加方法覆盖。

我也可以调整方法实现。不喜欢-doFoo的现有实现?这很酷;用你自己的替换它。等一下;如果方法是内联的,那么新的实现将永远不会被调用,因为-doBar实际上从未调用-doFoo方法。

唯一时间我可以看到这是可能的,如果有某种方法可以将方法注释为不可覆盖的方法。 But there's no way to do that,这个问题没有实际意义。而即便如此,它仍然是一个坏主意;只是因为编译器不允许你这样做并不意味着你不能在运行时解决它。而且,你会遇到问题。