object_setClass()的性能,而不是分配isa指针
我注意到与XCode(4.6)的最新更新,我被告知JSONKit.m
几行。 具体而言,设置对象类的行:
dictionary->isa = _JKDictionaryClass;
这些被标记为不推荐使用,注意首选方法是使用object_setClass()
:
object_setClass(dictionary, _JKDictionaryClass);
当我问到为什么宁愿简单地使警告消失时,答复是:
一切正常,即使新的Xcode版本抱怨,我不想:
1)testing每个项目,我使用JSONKit检查是否一切正常后object_setClass()
2)松散的CPU周期,这就是为什么我使用NSJSONSerialization JSONKit的例子。 我当前的应用程序分析重量为600K-1M的json文件
我们在这里谈论的是多大的performance?
注 :
我更感兴趣
dictionary->isa = _JKDictionaryClass
vs object_setClass()
比JSONKit
vs NSJSONSerialization
。
原因是函数调用总是有一些开销:参数应该被压入堆栈(也是调用者保存的寄存器),然后指令指针应该被更新,然后当函数返回时,所有这些都应该反向执行。 它通常比简单的解引用指针(它可以像mov [dest] [src]
一样简单)在计算上更昂贵。
推理与演出没有任何关系,从来没有。 将对象定义为具有isa
指针是一个实现细节,至less从Objective-C 2.0开始(在概念上已经持续了很长时间)。 Clang编译器和苹果,尤其是参与运行时优化的人员,除了能够将一个对象定义为拥有最快的内部结构,而不是始终保持这个isa
字段之外,没有什么比这更好。 isa
存在的事实,它存在于每个对象的开始,而isa
仅仅是一个Class
指针,这个事实总是在理论上受到改变。 到目前为止,还没有改变,因为兼容性的突破会导致比其他任何事情都更为严重。
此外, object_setClass
与object->isa = blah
的性能特征有点玩笑。 在硬件层面上,CPU很可能在影响你的代码之前,早就对函数调用的开销进行优化。 如果你担心pushq %rbp; movq %rsp, %rbp; movq %rsi, (%rdi); popq %rbp; ret
涉及的周期数, pushq %rbp; movq %rsp, %rbp; movq %rsi, (%rdi); popq %rbp; ret
pushq %rbp; movq %rsp, %rbp; movq %rsi, (%rdi); popq %rbp; ret
,你不再在Objective-C问题领域了 – 如果你的代码对五个指令所做的不同,你应该已经在C或汇编语言级别工作了。
甚至所有这一切,以这种方式设置对象的类别开始时没有什么好的理由。 你为什么在这个世界上做这个,对你有什么帮助?
最后,我可以补充说,Clang团队有更好的事情要做,而不是纯粹为了处理这种“performance”问题而添加警告。 几乎所有的警告(不是全部,但大多数)意味着你做错了什么,即使在你正在testing的情况下,它恰好在工作。 对于使用标记指针的任何对象,此代码已经中断。 这是Xcode试图告诉你的。
编辑 :有人指出,这个问题不是关于警告本身的原因,而是有关函数的特定性能特征。 正如我在我的回答中所提到的那样,性能影响非常小,如果它与您的代码相关,则不应该首先使用Objective-C。 我很抱歉误解了原来的问题。