2012-02-19 71 views
2

我可以定义一个具有属性的类来从课堂外访问我的ivars。是否可以使用课堂外的直接ivar访问来提高效率?

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

在C++中,我将使用访问器,但是在objective-c中,有些情况下我可能需要直接访问。消息传递系统会在访问器的性能方面产生很大的影响,这在某些情况下很重要,因为消息不像使用C++方法那样内联。

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

-(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->标量,该方法将运行速度快了很多,因为使用电话与访问会占用在这最CPU的循环。

与C++一样,我明白直接ivar访问一般是不鼓励的,但在这种情况下,速度问题时,它可以接受吗?如果没有,是否还有一种更优先的方法仍然使用Objective-C类?

+1

通常您会直接在C或C++中执行性能密集型部件。 – 2012-02-19 23:44:46

+1

您使用访问器时看到的性能影响有多大?你是否已经量化了“巨大的性能打击”以及直接访问伊娃的速度要快多少,还是这种先发制人的假设? – 2012-02-20 00:03:50

+0

@GeorgFritzsche是的,我通常这样做,但是当我想要在一个类接口中进行多态性,NSCoding和引用计数时弹出,而不是将它分解为structs/C++类和obj-c类。 – 2012-02-20 00:04:12

回答

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); 

BTW,上面绝对是vDSP_dotpr()候选人,但应性能测试。在很多情况下,当stride = 1时(因为您可以使用简单的增量而不是+= stride),简单循环比等效的vDSP调用要快。

+1

这些都是伟大的消费,谢谢。因此,如果您打算使用obj-c来处理这种事情,请参阅第一种方法是否可以将消息传递瓶颈分解为更长的块。其他优化技术听起来也很有趣。 – 2012-02-20 01:05:21

+0

“因此,如果你打算使用obj-c来处理这种事情,那么看看你是否可以将消息传递瓶颈分解为更长的块作为第一种方法。” - 确实如此。 – 2012-02-20 01:22:32

+0

正如我试图使用的移动功能到数组(totalOverArray)我意识到这不适用于我的情况,因为doWorkWithMyClass是polymorphed和行为因每个类而异。所以我会使用getScalars方法。 – 2012-02-20 02:17:03

1

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