Re[4]: Обработка массива в памяти
От: watch-maker  
Дата: 26.01.13 09:49
Оценка: 1 (1)
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, watch-maker, Вы писали:


WM>>Можно просто заменить цикл [0..n) на цикл [-n..0). Это позволит, не меняя направление просмотра массива, использовать упрощённое сравнение с нулём как признак завершения цикла. Собственно, компиляторы так тоже делают.

А>А это не усложнит индексацию по переменной цикла?
Просто базой будет служить не начало массива, а его конец. То есть код вида
T* base  = array + 0;
for (int i = 0; i < n; ++i)
  action(base[i]);
будет заменён на
T* base  = array + n;
for (int i = -n; i < 0; ++i)
  action(base[i]);
Как видно, тело цикла никак не изменилось. Изменилось лишь условие продолжения цикла (стало проще) и код инициализации цикла (стал сложнее). Так как обычно цикл делает более одной итерации, то условие проверяется чаще и на нём имеет смысл сэкономить.

Но разумеется, не стоит бросаться переписывать все циклы во вторую форму, ибо у них хуже читаемость, проверка условия в таких циклах редко является тормозом (а на суперскалярных процессорах отличий между двумя вариантами может вообще не быть), да и компилятор обычно сам способен сделать такую замену.
Ну и интересно ещё то, что компилятор часто использует два регистра для прохода по массиву: счётчик и указатель. Счётчик всегда движется к нулю, а указатель непосредственно индексирует обрабатываемый элемент. В таком случае различий между двумя вариантами не будет вообще.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.