Dol*_*hin 59 performance objective-c
我只是盯着玩Objective C(编写玩具iPhone应用程序),我很好奇用于发送消息的底层机制.我非常了解C++中的虚函数通常是如何实现的,以及相对于静态或非虚方法调用的成本是多少,但我没有任何Obj-C背景知道如何发送消息.浏览我发现这个松散的基准测试,它提到IMP缓存的消息比虚函数调用更快,而虚拟函数调用反过来比标准消息发送更快.
我不是要优化任何事情,只是更深入地了解消息的分派方式.
我知道其中一些问题可能是"依赖于实现的",但实际上只有一个实现非常重要.
Ale*_*ski 91
如何发送Obj-C消息?
使用运行时的objc_msgSend()函数调度Objective-C消息.在Apple文档中显示,该函数至少需要2个参数:
类的实例有一个isa指针,它是指向其类对象的指针.每个对象中的方法选择器存储在类对象的"表"中,objc_msgSend()函数跟随isa指向类对象的指针,查找此表,并检查该方法是否在类的表中.如果找不到它,它会在类的超类表中查找该方法.如果未找到,它将继续向上对象树,直到它找到方法或到达根对象(NSObject).此时,抛出异常.
实例方法指针如何被缓存,你是否(通常)通过阅读代码告诉消息是否会被缓存?
来自Apple关于消息传递的Objective-C运行时指南:
为了加速消息传递过程,运行时系统在使用它们时缓存方法的选择器和地址.每个类都有一个单独的缓存,它可以包含继承方法的选择器以及类中定义的方法.在搜索调度表之前,消息传递例程首先检查接收对象类的高速缓存(理论上可能会再次使用一次使用的方法).如果方法选择器位于缓存中,则消息传递仅比函数调用稍慢.一旦程序运行了足够长的时间来"预热"其缓存,它发送的几乎所有消息都会找到一个缓存的方法.随着程序的运行,缓存会动态增长以容纳新消息.
如上所述,一旦程序运行,缓存就开始发生,并且在程序运行足够长时间之后,大多数方法调用将通过缓存方法运行.正如它所说的那样,缓存在使用方法时发生,因此消息仅在使用时被缓存.
类方法本质上与C函数(或C++中的静态类方法)相同,还是有更多的东西?
类对象以类似于类实例的方式处理方法发送.每个类对象都有一个对象,它在一个名为a 的对象中存储自己的类方法metaclass.类对象有自己的isa指向其元类对象的指针,该对象又具有超级元类对象,它可以从中继承类对象.对类方法的方法调度如下:
isa指向元类对象的指针bbu*_*bum 19
我还在我的博客上的x86_64上通过objc_msgSend()的指令编写了一条指令,如果有人想深入探讨的话:
http://www.friday.com/bbum/2009/12/18/objc_msgsend-part-1-the-road-map/
| 归档时间: |
|
| 查看次数: |
18109 次 |
| 最近记录: |