Подтвердить что ты не робот

Приращение итераторов: ++ это более эффективно, чем это ++?

Возможный дубликат:
Есть ли разница в производительности между я ++ и ++ я на С++?

Я пишу программу, в которой итератор используется для прокрутки std::vector. Кто-то сказал мне, что выполнение ++ этого в инструкции for приводит к более эффективному коду. Другими словами, они говорят, что:

for ( vector<string>::iterator it=my_vector.begin(); it != my_vector.end(); ++it )

работает быстрее, чем

for ( vector<string>::iterator it=my_vector.begin(); it != my_vector.end(); it++ )

Это правда? Если да, то в чем причина повышения эффективности? Все это ++/++ это переносит итератор на следующий элемент в векторе, не так ли?

4b9b3361

Ответ 1

Причина, по которой ускоряется преинкремент, заключается в том, что пост-приращение должно вернуть копию старого значения. Поскольку GotW # 2, поместите его: "Preincrement более эффективен, чем постинкремент, потому что для postincrement объект должен увеличиваться, а затем возвращать временное, содержащее его старое Обратите внимание, что это верно даже для встроенных типов, таких как int."

GotW # 55 предоставляет каноническую форму постинкремента, которая показывает, что она должна делать преинкремент плюс еще несколько работ:

T T::operator++(int)
{
  T old( *this ); // remember our original value
  ++*this;        // always implement postincrement
                  //  in terms of preincrement
  return old;     // return our original value
}

Как отмечали другие, некоторые компиляторы могут в некоторых случаях оптимизировать это, но если вы не используете возвращаемое значение, то не стоит полагаться на эту оптимизацию. Кроме того, разница в производительности, вероятно, будет очень мала для типов, которые имеют тривиальные конструкторы копирования, хотя я думаю, что использование preincrement является хорошей привычкой в ​​С++.

Ответ 2

Это вряд ли имеет значение для вектора.

В общем случае ++it крайне маловероятно, чтобы он был медленнее, чем it++ (предполагая разумную реализацию, если они перегружены), и просто может быть быстрее. Причина в том, что если сам класс итератора является вообще сложным, то, поскольку it++ должен вернуть значение до того, как it будет увеличено, реализация, как правило, сделает копию.

Итераторы векторов, вероятно, являются "просто указателями" (в оптимизированных, не-отладочных сборках), и оба operator++ будут включены. Поскольку возвращаемое значение не используется, копия обычно будет удалена. Так что это не будет иметь никакого значения. Я привык печатать ++it, потому что:

1) В какой-то день это может повлиять на некоторый тип итератора, и я не хочу делать что-то особенное для этого типа.

2) Лично я считаю, что префиксный оператор более четко выражает намерение: "увеличивайте его", а не "используйте его, а затем увеличивайте".

Ответ 3

it ++ выполняет следующие операции:

  • создать его копию
  • увеличить его
  • вернуть исходный (без приращения) его

++ выполняет следующие операции:

  • увеличить его
  • вернуть его

Поскольку он ++ создает копию, можно сказать, что она "медленнее". Однако любой достойный компилятор оптимизирует эту разницу для большинства определенных типов. Для некоторых пользовательских типов он может быть быстрее.

Ответ 4

Иногда да. С некоторыми это будет оптимизировано и будет одинаковым. Для std::vector < > (и других std-итераторов), скорее всего, будет оптимизировано одинаковое.

Ответ 5

Есть вероятность, что он ++ создаст временную копию.

Кроме того, в С++ существует вероятность того, что кто-то перегрузил оператор postincrement.

Обе эти вещи могут снизить производительность и преинкремент. На практике это тоже не имеет большого значения. В частности, временная копия будет оптимизирована большинством компиляторов, поскольку в третьем выражении цикла For отсутствуют побочные эффекты.

Ответ 6

yes ++ это более эффективно, потому что ему нужно вернуть копию объекта, а затем увеличивать его.

Ответ 7

Да. Насколько я помню, ++ он эффективнее, чем ++, потому что он ++ создает временный объект, а ++ - нет.