CoreFoundation和Foundation的区别

33

在 iPhone 开发中,速度至关重要。有没有人知道使用 CoreFoundation 类型(例如 CFMutableDictionaryRef)与 Foundation 类型(它的对应物 NSMutableDictionary)之间是否存在速度差异。

我认为操作 CF 类型会更快,因为它不必传递 ObjC 运行时消息,这是一个没有根据的假设吗?有没有人真正研究过这个问题?


4
当您说“速度至上”时,是指开发速度还是已开发应用程序的速度? - JeremyP
应用程序本身的速度。 - grmartin
2个回答

48
从技术角度来看,是的,它更快,正是因为这个原因。
从实际角度来看,不,它不会更快。一方面,速度差异微乎其微。我们谈论的是在整个过程生命周期中节省了几毫秒的时间。
在iPhone上节省的时间可能会更多,但仍然非常微小。你把时间花在使用工具检测你的应用程序瓶颈并修复自己代码中的问题上更加划算。
这就是Foundation变得更快的地方:你的时间。
尽可能使用Foundation的autorelease特性的代码通过避免容易避免的内存泄漏(即遗漏写或未能到达“release”消息)来节省您大量的时间和麻烦。CF没有autorelease,所以你必须记得明确地释放你创建或复制的所有内容,并且当你忘记或未能到达那段代码时(我是指"当下"——我是根据经验说的),你将花费更多的时间寻找内存泄漏。静态分析器有所帮助,但永远无法捕获所有漏洞。
(你在技术上可以自动释放CF对象,但是要做到这一点的代码非常丑陋,而且你只是在削弱你已经微不足道的速度优势。)
因此,尽可能使用Foundation。不要过分依赖autorelease;即使在纯Cocoa中,仍然有时需要明确释放对象(主要是紧密的循环),而在Cocoa Touch中,这一点更加重要(因为iOS会在你分配太多内存时杀死你的应用程序,所以你需要尽快释放大型对象,例如图像)。但通常情况下,autorelease为您节省的时间比CF节省的时间更多。
非与时间有关的原因是,Objective-C代码将参数名(来自消息选择器)与值混合在一起,比基于C函数的代码容易阅读得多。这可能不会让你的工作变得更快,但肯定会让它更有趣。

当我使用CF对象时,我总是使用一个C++包装器,其析构函数负责CFRelease,并且还具有复制构造函数等,可以正确处理。对于我来说,将CF对象放入这样的包装器中在创建时记住并不比记住Foundation对象自动释放更困难。但我同意任何时间差异可能是微不足道的,并且应该让分析器指导优化工作。 - JWWalker
我正在寻找一种将自定义结构化文本格式的大量数据转换为iPhone可使用的真正对象的方法。但是,我将标记此问题为已解决。 - grmartin
jcstanton:首先用Cocoa编写它,然后进行分析。我几乎可以保证Objective-C消息传递(objc_msgSend及其相关函数)不会是分析结果中最昂贵的部分。如果它确实是,通常意味着您在第一次发送过多的消息,并且通过进行过多的函数调用来解决问题并不能真正解决您的问题。 - Peter Hosey
2
多年以后,有一件事需要认识到:如今CF的大部分代码实际上是用ObjC编写的。通过使用C API,你可能会遇到一些性能问题,而不是获得加速。 - Catfish_Man
Darwin基础是主要用Objective-C编写的,而Objective-C运行时不是Swift开源项目的一部分。然而,CoreFoundation是一个可移植的C库,不需要Objective-C运行时。它包含了许多通过Foundation API公开的行为。 - TimBigDev
显示剩余2条评论

6
在CF函数中编写代码确实可以提高应用程序性能,但是如果您真的想获得终极性能提升,您可以直接编写机器代码,它没有比这更快的了。不过这将是一种极端的方法。
高级语言结构比低级语言结构更可取,至少对于Peter Hosey提到的原因是如此。此外,过早优化可能会导致项目失败,因为开发人员更关注应用程序的非功能方面而不是功能方面。
如果,在拥有完全功能的应用程序之后,您觉得某些代码部分存在性能瓶颈,那么您可以尝试通过将其重写为低级语言结构来进行优化。您至少需要与当前代码进行比较,以确保低级代码的行为符合预期(手动或单元测试都可以解决问题)。
我的意思是,虽然我们不应忽略性能,但我们不应将其作为首要目标。功能方面同样重要(甚至更重要)。如果您没有一个交付其功能规格的应用程序,那么它可能是地球上最快的,但人们仍然不会使用它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接