Обычно я думаю, что преинкремент более эффективен, чем постинкремент в C++. Но когда я недавно прочитал книгу Game Engine Architecture (2nd ed.), в одном из разделов говорится, что постинкремент предпочтительнее, чем преинкремент в цикле for. Потому что, как я цитирую, "preincrement вводит зависимость данных в ваш код - ЦП должен дождаться завершения операции приращения, прежде чем его значение можно будет использовать в выражении". Это правда? (Это действительно подрывает мое представление об этой проблеме.)
Вот цитата из раздела на случай, если вы заинтересованы:
5.3.2.1 Преинкремент против постинкремента
Обратите внимание, что в приведенном выше примере мы используем постинкрементный оператор C++,
p++
, а не прединкрементный оператор,++p
. Это тонкая, но иногда важная оптимизация. Оператор preincrement увеличивает содержимое переменной до того, как ее (теперь измененное) значение используется в выражении. Оператор postincrement увеличивает содержимое переменной после ее использования. Это означает, что написание++p
вводит зависимость данных в ваш код - ЦП должен ждать завершения операции приращения, прежде чем его значение можно будет использовать в выражении. На глубоко конвейерном процессоре это приводит к остановке. С другой стороны, сp++
нет зависимости от данных. Значение переменной можно использовать немедленно, а операция приращения может произойти позже или параллельно с ее использованием. В любом случае, в pipeопровод не поступает стойло.Конечно, в выражении 'update' цикла
for
(for(init_expr; test_expr; update_expr) { ... }
) не должно быть различий между pre- и постинкремент. Это потому, что любой хороший компилятор признает, что значение переменной не используется вupdate_expr
. Но в тех случаях, когда значение используется, postincrement лучше, потому что он не вводит срыв в конвейере процессоров. Поэтому, это хорошо, чтобы привыкнуть всегда использовать postincrement, если вам абсолютно не нужна семантика preincrement.
Изменение: Добавить "приведенный выше пример".
void processArray(int container[], int numElements)
{
int* pBegin = &container[0];
int* pEnd = &container[numElements];
for (int* p = pBegin; p != pEnd; p++)
{
int element = *p;
// process element...
}
}
void processList(std::list<int>& container)
{
std::list<int>::iterator pBegin = container.begin();
std::list<int>::iterator pEnd = container.end();
std::list<inf>::iterator p;
for (p = pBegin; p != pEnd; p++)
{
int element = *p;
// process element...
}
}