【问题标题】:How much quicker is public instance variable access compared to properties in Objective-C与 Objective-C 中的属性相比,公共实例变量的访问速度快了多少
【发布时间】:2016-12-25 17:57:14
【问题描述】:

我的公司完成了一个新的游戏引擎,它(像大多数引擎一样)是 CPU 密集型的。它是用 Objective-C 编写的,大多数经常访问的核心游戏项目都存储在对象属性中。其中大部分是自动合成的,只需存储和读取即可。

通过将核心游戏引擎项目中的属性更改为公共实例变量,我们可以获得多少速度(如果有的话)?

因此,它会像这样使用属性声明和访问

@property (nonatomic) CMLocation location;
node.location.x;

现在应该是:

@public:
   CMLocation location
node->location->x

从逻辑上讲,我认为 ivars 会快得多,因为它应该是一个几乎单一的时钟滴答操作(假设没有缓存未命中),但也许编译器现在调整了这种事情并且合成属性也一样快。

【问题讨论】:

  • 对其进行基准测试。如果速度可以接受,坚持属性。代码的清晰性也很重要。
  • 像你这样声明的原子属性肯定会比 ivar 慢
  • 谢谢,我把它改成了非原子的,因为这实际上是我们使用它的方式。
  • 公共实例变量是个坏主意。不要公开内部实现细节。
  • 让我觉得可能是“过早的优化”。提防为了理论优化而优化代码,牺牲代码的可维护性。当然,如果这是一个实际的瓶颈,那么就做出这种牺牲,但这里不太可能出现这种情况。如果你经常调用它以至于它确实产生了任何可观察到的影响,那么问题可能在于更广泛的设计,而不是这个访问器。但只有在更广泛的背景下审查这一点并对您的代码进行基准测试才能验证这一点。

标签: ios objective-c performance oop properties


【解决方案1】:

无法用数字回答,但尝试描述“幕后”的机制

当我们通过node->location->x 访问属性时——这是最快的方式,只需在内存中查找地址,纯 c 风格。

当我们通过node.location.x 访问时,obj-c 为属性调用getter 方法,这不仅仅是经典的函数调用——obj-c 执行objc_msgSend( node, @selector( location)),它通过字符串名称执行选择器查找。你可以在这里找到这个过程的非常清晰的描述:https://www.mulle-kybernetik.com/artikel/Optimization/opti-3.html

因此,如果您的代码经常执行并且它是性能瓶颈 - 是的,您应该将其重写为 c 风格。另外,请记住,结构属性是直接访问的,并且在重写时要注意安全 - 你不再有 nil 检查。

附:您可以使用 Instruments 测量性能以发现瓶颈并仅优化重要的代码块 - 这是优化的明智方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-05
    • 1970-01-01
    • 2013-05-19
    • 2012-02-02
    • 2013-10-06
    • 1970-01-01
    • 2017-09-07
    • 2020-06-10
    相关资源
    最近更新 更多