Разница в производительности при доступе к элементу в массиве по сравнению с указателем? - PullRequest
2 голосов
/ 12 марта 2012

Я новичок в C - привык к языкам сценариев, таким как, PHP, JS, Ruby и т. Д. Получил запрос относительно производительности. Я знаю, что нельзя оптимизировать микрооптимизацию слишком рано - однако я пишу расширение Ruby C для Google SketchUp, где я делаю много трехмерных вычислений, поэтому производительность является проблемой. (И этот вопрос также для изучения того, как работает 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 ]

5 голосов
/ 12 марта 2012

Вряд ли будет существенная разница.Возможно, выданный код будет идентичным.Это предполагает довольно компетентный компилятор с включенной оптимизацией.Возможно, вы захотите взглянуть на дизассемблированный код, просто чтобы почувствовать некоторые вещи, которые использует оптимизатор Си.Вы можете сделать вывод: «мой код искажен до неузнаваемости, нет смысла беспокоиться о подобных вещах на данном этапе», что является хорошим инстинктом.

Возможно, первый код мог бы быть даже быстрее, если бывведение указателя item должно было как-то мешать развертыванию цикла или другой оптимизации, которую ваш компилятор выполняет в первую очередь.Или может быть так, что оптимизатор может выяснить, что arr[i].foo равно stack_pointer + sizeof(FooBar) * i, но не сможет выяснить это после того, как вы используете указатель, и в конечном итоге использовать дополнительный регистр, что-то еще, с влиянием на производительность.Но я дико размышляю над этим: обычно нет практически никакой разницы между доступом к массиву по указателю или по индексу, я просто хочу сказать, что любая разница может возникнуть по удивительным причинам.

2 голосов
/ 12 марта 2012

Если бы волновались и чувствовали себя микрооптимизаторами (или просто были в ориентированном на указатель настроении), я бы пропустил целочисленный индекс и просто использовал бы указатели повсюду:

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

Нообратите внимание: я не скомпилировал это (или ваш код) и не учел инструкции, что вам и нужно сделать.Так же, как запуск и измерение, конечно, поскольку некоторые комбинации нескольких команд могут быть быстрее, чем короткие последовательности других инструкций и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...