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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  1. создать его копию
  2. увеличивать его
  3. вернуть исходное (без приращения) значение

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

  1. увеличивать его
  2. верни это

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

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

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

  • максимальное значение int
  • Как отсортировать std :: vector по значениям другого std :: vector?
  • В каком сценарии я использую конкретный контейнер STL?
  • Зачем использовать начальные и конечные функции не-членов в C ++ 11?
  • Является ли list :: size () действительно O (n)?
  • Является ли std :: unique_ptr необходимым для определения полного определения T?
  • как вы вставляете значение в отсортированный вектор?
  • std :: map, указатель на значение ключа карты, возможно ли это?
  • char * vs std :: string в c ++
  • Итерации ключей на карте C ++
  • push_back vs emplace_back
  • Давайте будем гением компьютера.