是否可以从课外使用直接的ivar访问以提高效率?

时间:2012-02-19 23:42:31

标签: objective-c performance class ivar

我可以定义一个具有属性的类,以便从类外部访问我的ivars。

我也可以使用myInst-> ivar语法以C-struct方式访问。

在C ++中,我会使用访问器,但在objective-c中,有些情况下我可能需要直接访问。消息传递系统在某些上下文中对访问器造成了很大的性能损失,因为消息没有像C ++方法那样内联。

例如,在具有名为标量的ivar和在其上定义的属性的类中。标量是一个简单的浮点值:

-(void) doWorkWithMyClass:(MyClass*)myinst
{
   // array and other locals declaration omitted 
   for (int i = 0; i < reallyBigX; i++) {
      result += [myinst scalar] * array[i];
      [myinst computeNextScalar:i];
   }
}

如果我将[myinst标量]更改为myinst-&gt;标量,则该方法将运行得更快,因为使用访问器调用会占用此循环中的大部分CPU。

与C ++一样,我理解一般不鼓励直接进行ivar访问,但在这种情况下,当速度很重要时,它是否可以接受?如果没有,是否有更优选的方法仍使用objective-c类?

2 个答案:

答案 0 :(得分:6)

当它对性能产生重大影响时,很多事情都会被接受,但在你给出的例子中,似乎有更好的解决方案。

首先,为什么[myinst computeNextScalar:i]没有返回新的标量?如果你这样做,你就不需要获取它,一切都会快得多。

无法将作品移至myinst?我的意思是,你不能创造类似的东西:

result = [myinst totalOverArray:array];

如果reallyBigX真的很大,那么你应该在这里考虑Accelerate.framework。它可以显着提高您似乎正在进行的操作的性能。 (你必须使用Accelerate框架进行性能测试。对于某些操作来说,它可能会慢得多,但这个操作可能会更快。)

最后,考虑Objective-C get...模式。它看起来像这样:

int *scalars = calloc(reallyBigX, sizeof(int));
[myinst getScalars:scalars range:NSMakeRange(0, reallyBigX)];
for (int i = 0; i < reallyBigX; i++) {
   result += scalars[i] * array[i];
}
free(scalars);
顺便说一句,上面肯定是vDSP_dotpr()的候选者,尽管你应该对它进行性能测试。在很多情况下,当stride = 1时,简单循环比等效vDSP调用快(因为你可以使用简单的增量而不是+= stride)。

答案 1 :(得分:1)

是的,可以接受:部分引入了@public@private等访问修饰符,以支持需要从类外部访问ivars的设计。但是,你应该避免直接写入ivars。