ma1*_*w28 13 performance objective-c llvm inline-functions
LLVM是否会在可能的情况下自动将Objective-C方法转换为内联函数?
(即,为一块代码创建一个Objective-C方法,你可以在其他方式粘贴内联吗?)
如果LLVM不执行此优化,为什么不呢?如果是,(a)是否有必须为此设置的某些构建设置?(b)如何判断是否内联Objective-C方法?
Jos*_*erg 12
不,因为如果可以执行这些优化,则无法在Obj-C运行时的上下文中知道.要记住的是Obj-C方法是由消息发送调用的,这些消息不仅仅来自[myObject doSomething]语法.
考虑[obj performSelector:NSSelectorFromString(@"hello")]到这可能发生的事实意味着不可能内联任何方法.
当类接收到消息时,也会发生一系列事件,这些事件可以重新路由,甚至更改正在发送的消息.这在邮件发送下透明地发生.
不是.目标-C的一个基本特征是消息调度(记住在Obj-C中发送消息,你不调用方法)在运行时动态发生,而不是在编译时发生.
因此,Obj-C中的消息调度总是比纯函数调用慢一点(即使函数没有内联).
让我们假设编译器内联一个方法:
@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_allocateClassPair和class_addMethod动态创建子类并添加方法覆盖来完成此操作.
我也可以调整方法实现.不喜欢现有的实施-doFoo吗?这很酷; 用你自己的替换它.等一下; 如果方法是内联的,那么新的实现永远不会被调用,因为-doBar它实际上从未调用过该-doFoo方法.
在只有我能看到这是可能的时间,如果有某种方式来标注方法为未覆盖的.但是没有办法做到这一点,所以这个问题没有实际意义.而即使这样,它仍然是一个坏主意; 只是因为编译器不允许你这样做并不意味着你不能在运行时解决它.而且,你会遇到问题.
| 归档时间: |
|
| 查看次数: |
2156 次 |
| 最近记录: |