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

ma1*_*w28 13 performance objective-c llvm inline-functions

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

    (即,为一块代码创建一个Objective-C方法,你可以在其他方式粘贴内联吗?)

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

Jos*_*erg 12

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

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

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

  • 因为它们可以在运行时轻易地换出.我可以在3或4行运行时代码中更改任何方法的实现. (7认同)

Ole*_*ann 9

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

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


Dav*_*ong 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
Run Code Online (Sandbox Code Playgroud)

所以-doBar基本上变成:

- (void)doBar {
  [self doAwesomeStuff];
  {
    NSLog(@"doing foo!");
  }
}
Run Code Online (Sandbox Code Playgroud)

真棒,看起来它会更快,对吧?我们通过不打电话给自己保存了十几个指令objc_msgSend.因此,您将其打包并在线发布为.a文件.

NSCleverCoder出现并说"但我想doFoo多做一点",所以他这样做:

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

当他试图运行它时,它永远不会被调用,因为AwesomeClass从来没有实际调用该-doFoo方法.

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

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

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

只有我能看到这是可能的时间,如果有某种方式来标注方法为未覆盖的.但是没有办法做到这一点,所以这个问题没有实际意义.而即使这样,它仍然是一个坏主意; 只是因为编译器不允许你这样做并不意味着你不能在运行时解决它.而且,你会遇到问题.