是否比局部变量多次引用实例变量数组元素效率较低?

时间:2012-08-25 09:18:21

标签: objective-c arrays performance variables instance-variables

如果我这样做:

foos[i] = [[Foo alloc] init];
foos[i].prop = @"bar";
[foos[i] baz];

......效率低于:

Foo *foo = [[Foo alloc] init];
foo.prop = @"bar";
[foo baz];
foos[i] = foo;

还是等同?

3 个答案:

答案 0 :(得分:2)

它们不是等价的,但它们足够接近,以至于优化编译器可能生成完全相同的二进制代码。

即使它没有,你也很难衡量差异(除非foos是一个非常昂贵的operator[]的C ++类)。在分析器说不然之前 - 优化这段代码还为时过早。

答案 1 :(得分:1)

如果您的数组是一个简单的C数组(Foo * array[11];),那么它不会对性能产生重大影响。

如果你的数组是NSMutableArray(或另一个可订阅的NS类型),那么它必须重复调用方法的实现(使用短路调度),这样会引入一些开销。虽然有些人会认为它是微观优化。在这种情况下,编译器不能知道实现返回的内容,因此它不能省略调用。


以下是基本的挂钟时间结果:

  

MRC:

     
    

NSArray:27秒

         

C阵列:18秒

  
     

ARC:

     
    

NSArray:31秒

         

C阵列:18秒

  

和程序(您可以执行明显的ARC更改以测试ARC):

const int NIter = 10000;

__attribute__((noinline)) void fn1() {
  @autoreleasepool {
    NSMutableArray * foos = [NSMutableArray array];
    for (size_t idx = 0; idx < NIter; ++idx) {
      NSMutableString * str = [NSMutableString new];
      foos[0] = str;
      [foos[0] length];
      [foos removeAllObjects];
      [str release];
    }
  }
}

__attribute__((noinline)) void fn2() {
  @autoreleasepool {
    NSMutableString * foos[1];
    for (size_t idx = 0; idx < NIter; ++idx) {
      foos[0] = [NSMutableString new];
      [foos[0] length];
      [foos[0] release];
      foos[0] = 0;
    }
  }
}

int main() {
  for (size_t idx = 0; idx < NIter; ++idx) {
    if (UseNSArray) {
      fn1();
    }
    else {
      fn2();
    }
  }
  return 0;
}

答案 2 :(得分:0)

当然,除非编译器将其优化掉。是否显着效率低下是另一回事,这取决于您的代码正在做什么。担心像这样的微观优化通常是徒劳的,除非你已经有证据证明这附近存在效率问题。