我是Cocoa的新手,在我开始使用类别之前有一个小问题.
假设您向NSString添加一个新方法.这是否会影响正常NSString消息的性能,还是仅在方法调用与标准方法集不匹配时才检查类别方法?
所有方法都使用动态调度发送,消息到类别方法不会干扰"正常"消息.
从性能方面来看,运行时处理将方法与所讨论的类相关联,因此存在一次性成本,但每个单独对象没有变化.我不会关注类别的性能,而是要确保通过类别添加的方法不包括默认方法或其他类别中指定的方法.这就是问题通常开始的地方.
一般来说,没有.
objc_msgSend()
保留最近的伪最近最少使用高速缓存SEL
来IMP
查找在每个阶级基础.与往常一样,具体是"实现私有细节",但O(1)
无论选择器的数量多少,可以合理地说查找时间平均为〜.最常见的方法是使用小型哈希表 - 如果选择器位于缓存中,则调度基本上是即时的.如果选择器不在缓存中,那么它需要执行"慢速路径"昂贵的查找.
然而,即使是"慢速路径"也可以相当快.可以转向的任何数量的数据结构,例如红黑树,提供出色的亚指数查找时间,无论选择器的数量如何,都可以很好地扩展O(log2(selectorCount))
.同样,如何libobjc
处理这些类型的细节是私有的,但是有很多数据结构可以轻松扩展,无论要搜索的项目数量是多少都没有理由这种事情甚至应该在你的雷达上.
快速检查通过nm
基金会中的7771选择器和AppKit中的27510选择器,在两者之间共有35281个选择器.投入QuickTime,CoreData,WebKit,Quartz,轻松实现50K选择器.使用log2
查找时间增长率,选择器数量加倍将使最坏情况时间增加不到10%.
总结: objc_msgSend()
使用一个小的基于散列的缓存为O(1)
最近使用的选择器提供查找时间......并且存在非常高程度的时间局部性,因此绝大多数调度都是及时完成的,O(1)
无论存在多少选择器在系统中.缓存的自然效果是根据您的特定使用模式"调整"自身.即使在高速缓存未命中,也可能是一个合理的猜测,最坏情况的查找时间是〜O(log2(selectorCount))
约束,这是非常好的,并且它可能比实际中更好.
为了它的价值,我花了很多时间调整代码以提高速度.即使是多线程的东西,我把所有的CPU都做大量的分析 - > NSView/OpenGL重结果渲染,所有编码都在Objective-C中,我只会看到objc_msgSend()
占用1-4%的CPU时Shark.app
......这是最糟糕的情况,进行大量的Objective-C消息调度.这对我来说从来都不是问题,无论是什么样的速度惩罚,它都可以轻松地实现100X编程效率.
也可以看看:
Mulle kybernetiK- Obj-C优化:更快的objc_msgSend
Objective-C 2.0运行时编程指南 - 消息
Apple Objective-C运行时 - objc4-437.tar.gz
编辑:这有多奇怪:专利5960197 - 面向对象C的编译器调度功能.不能说我知道整个Obj-C消息调度系统已获得专利....我猜你真的可以获得任何专利.宝贝,我要去拿字母表专利并收取大笔费用!