访问数组中的项与指针引用的性能差异?

时间:2012-03-12 12:19:15

标签: c performance

我很喜欢C - 用于脚本语言,如PHP,JS,Ruby等。有关于性能的查询。我知道不应该过早地进行微优化 - 但是,我正在为Google SketchUp编写Ruby C扩展,我正在进行大量的3D计算,因此性能是一个问题。 (这个问题也是为了解C的工作原理。)

通常会进行多次迭代来处理所有3D数据,因此我正在尝试找出可能更快的内容。

我想知道如果我对该数组条目进行指针引用,多次访问数组条目会更快吗?常见的做法是什么?

struct FooBar arr[10];
int i;
for ( i = 0; i < 10; i++ ) {
  arr[i].foo = 10;
  arr[i].bar = 20;
  arr[i].biz = 30;
  arr[i].baz = 40;
}

这会更快还是更慢?为什么呢?

struct FooBar arr[10], *item;
int i;
for ( i = 0; i < 10; i++ ) {
  item = &arr[i];
  item->foo = 10;
  item->bar = 20;
  item->biz = 30;
  item->baz = 40;
}

我环顾四周,发现有关变量与指针的讨论 - 通常说指针需要额外的步骤,因为它必须查找地址,然后查找值 - 但总的来说没有一点点击中。

但我想知道的是,如果访问C中的数组条目会有很大的性能影响吗?在Ruby中,如果您需要多次访问它,则可以更快地引用该条目 - 但这是Ruby ...

2 个答案:

答案 0 :(得分:5)

不太可能存在显着差异。可能发出的代码是相同的。这假设一个模糊的编译器,启用了优化。您可能希望查看反汇编代码,只是为了了解C优化器可以实现的一些功能。你可能会得出这样的结论:“我的代码已经超出了所有人的认可,在这个阶段就没有必要担心这种事情了”,这是一种很好的直觉。

可以想象,第一个代码甚至可能更快,如果引入item指针会以某种方式干扰任何循环展开或编译器在第一个上执行的其他优化。或者可能是优化器可以发现arr[i].foo等于stack_pointer + sizeof(FooBar) * i,但是一旦使用指针就无法弄清楚,并最终使用额外的寄存器,溢出其他东西,性能影响。但是我在这一点上疯狂地猜测:通过指针或索引访问数组之间通常几乎没有区别,我的观点是,出现任何差异都可能出于令人惊讶的原因。

答案 1 :(得分:2)

如果感到担心,并感觉像微优化它(或者只是处于指针导向的情绪),我会跳过整数索引并且只使用指针:

struct FooBar arr[10], *item, *end = arr + sizeof arr / sizeof *arr;
for (item = arr; item < end; item++)
  item->foo = 10;
  item->bar = 20;
  item->biz = 30;
  item->baz = 40;
}

但是请注意:我没有编译这个(或你的代码)并计算了指令,这是你需要做的。除了运行它和测量当然,因为多个指令的某些组合可能比其他指令的较短序列更快,等等。