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_setClassobject->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。 我很抱歉误解了原来的问题。