Приращение iteratorов: ++ это более эффективно, чем это ++?
Возможный дубликат:
Есть ли разница в производительности между i ++ и ++ i в C ++?
Я пишу программу, где iterator используется для прогона std :: vector. Кто-то сказал мне, что выполнение ++ этого в инструкции for приводит к более эффективному коду. Другими словами, они говорят, что:
for ( vector::iterator it=my_vector.begin(); it != my_vector.end(); ++it )
работает быстрее, чем
- Можно ли выразить «тип» lambda-выражения?
- Использование локальных classов с алгоритмами STL
- std :: transform () и toupper (), нет соответствующей функции
- У boost есть тип данных для заданных операций, который проще, чем STL?
- Вызывает ли std :: list :: remove метод деструктор вызова каждого удаленного элемента?
for ( vector::iterator it=my_vector.begin(); it != my_vector.end(); it++ )
Это правда? Если да, то в чем причина повышения эффективности? Все это ++ / ++ это переносит iterator на следующий элемент в векторе, не так ли?
- Как указать указатель на перегруженную функцию?
- Как преобразовать wstring в строку?
- Почему контейнеры STL не имеют виртуальных деструкторов?
- Почему это нормально, чтобы вернуть вектор из функции?
- C ++ сортировка и отслеживание индексов
- Почему std :: map реализована как красно-черное дерево?
- Добавление вектора к вектору
- Есть ли готовая готовая к запуску очередь или хеш-реализация в C ++
Причина, по которой ускоряется прекурсор, заключается в том, что пост-инкремент должен вернуть копию старого значения. Как указывал 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 нет побочных эффектов.
он ++ выполняет следующие операции:
- создать его копию
- увеличивать его
- вернуть исходное (без приращения) значение
++ он выполняет следующие операции:
- увеличивать его
- верни это
Поскольку он ++ создает копию, можно сказать, что она «медленнее». Однако любой достойный компилятор оптимизирует эту разницу для большинства определенных типов. Для некоторых пользовательских типов это может быть быстрее.
yes ++ это более эффективно, потому что он ++ должен возвращать копию объекта, а затем увеличивать его.
Да. Насколько я помню, ++ он эффективнее, чем ++, потому что он ++ создает временный объект, а ++ – нет.