我找不到关于现实生活项目中 ARC 性能影响的客观研究。 The official doc 说
它已被技术迷们转述/变形为“ARC 更快”。
我所知道的是我所测量的。我们最近将我们的 iOS 项目迁移到了 ARC,并且在我们代码的一些 CPU 密集型区域之前/之后做了一些性能测量(生产代码,当然是使用 -Os
标志编译的)。
我观察到 70%(是 70%)的性能回归。使用 Instruments 来跟踪保留/释放事件,我意识到编译器在您不会这样做的区域(在 ARC 之前的环境中)引入了很多保留/释放对。基本上,任何临时都会变得强大。我相信,这就是性能回归的根源。
迁移前的原始代码已经相当优化了。几乎没有任何自动发布完成。因此,切换到 ARC 几乎没有改进的余地。
幸运的是,Instruments 能够向我展示 ARC 引入的最昂贵的保留/释放,并且我能够使用 __unsafe_unretained 停用它们。这稍微减轻了性能回归。
有没有人有关于这个或其他技术的任何信息来避免性能损失? (除了停用 ARC)
谢谢。
编辑:
我并不是说 ARC 因为性能影响而不好。使用ARC的优势在很大程度上优于性能回归(在我们的代码中,回归没有任何可见的效果,所以我放弃了)。我认为ARC是一项非常好的技术。我永远不会回到 MRC。我更多是出于好奇问这个问题。
我只是对有关该主题的绝大多数博客(例如 here and there )或多或少给人的印象是 ARC 代码将比 MRC 代码更快(这是我在动手之前相信的) .我真的觉得在一些微基准测试之外情况并非如此。充其量你可以希望与 MRC 相提并论,而不是更快。我做了一些其他涉及对象操作的简单测试(比如计算文档中的单词)。每次 ARC 都变慢了(认为没有我最初谈论的 70% 性能回归那么糟糕)
\begin{讽刺}
事实上,上述文档确实回答了这个问题:
这显然应该理解为
\begin{模仿}
\end{模仿}
\end{讽刺}
最佳答案
这是我的 ARC vs MRC performance measurements 。性能测试项目为 available on github,因此您可以添加自己的测试。只要确保在设备上运行它。模拟器中的结果是有偏差的,并且通常有利于 MRC。
总结一下:
ARC 和 MRC 通常是相同的速度 。一般来说,代码在 ARC 下应该更快,但紧密循环可能会更慢并且明显如此。
在低级测试中,由于优化(自动释放返回,@autoreleasepool),ARC 在速度方面比 MRC 更具优势。
只要应用程序是单线程的,ARC 会在某些代码中插入额外的保留/释放,这在 MRC 下并不是绝对必要的。这样的代码在 ARC 下可能会更慢,尽管它只会在紧密循环中产生差异并且在很大程度上取决于相关代码。
例如,即使在 MRC 下,接收对象的方法也应该保留它,因为它可能在方法运行时在多线程应用程序中被释放。您可以在 MRC 中省略该代码这一事实使其更快,但本质上更不安全(尽管您很少遇到这样的问题,OTOH,如果您希望您没有遇到的话)。例子:
-(void) someMethod:(id)object
{
[object retain]; // inserted by ARC, good practice under MRC
[object doSomething];
[object doAnotherThing];
[object release]; // inserted by ARC, good practice under MRC
}
由于这个原因,我在测试项目中使用的遗传算法是 ,ARC 大约慢了 40%。这是一个糟糕的(极端)示例,因为对于这种算法,由于对 NSMutableArray 和 NSNumber 对象进行了大量插入/删除操作,因此通过在 C 中重写关键代码部分,您应该会看到更大的性能改进。
完全忽略 ARC 是完全疏忽的,因为在某些情况下它可能会更慢 。如果您发现这些情况对性能至关重要,那么
-fno-objc-arc
该代码或用 C 重写它。出于性能方面的考虑,不应考虑支持或反对 ARC。 ARC is a tool that make's a programmer's job a lot easier。由您决定是否愿意浪费时间尝试查找泄漏的对象和悬空指针崩溃,以至于您宁愿坚持使用 MRC。
关于objective-c - 是否有任何关于使用 ARC 的性能影响的具体研究?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12527286/