Имеют ли операторы увеличения / декремента до и после в C ++ одинаковую производительность в цикле?[дубликат]

StackOverflow https://stackoverflow.com/questions/631506

  •  08-07-2019
  •  | 
  •  

Вопрос

Рассмотрим следующие два примера.

class ClassOne
{
 //class definition is here
};

std::vector< ClassOne > myListOfObjects;

std::vector< ClassOne >::const_iterator iter = myListOfObjects.begin();

Example 1: 
for( ; iter < myListOfObjects.end(); **++iter**)
{
   //some operations
}

OR

Example 2: 
for( ; iter < myListOfObjects.end(); **iter++**)
{
   //some operations
}

Какой из них быстрее ?++iter или iter++ в контексте цикла.

Причина закрытия:

Скопировано из поста Брайана (чтобы сделать вопрос более кратким).

Вы также могли бы попробовать задать один из этих похожих вопросов: здесь или здесь или здесь или здесь.

Это было полезно?

Решение

Как указано в этом ответе , предварительно быстрее. Они одинаковы, когда вы имеете дело с примитивами (int, char и т. Д.). В этом случае они вызывают перегруженные операторы.

Другие советы

Нет, у них не одинаковая производительность:

  • Postincrement создаст копию, затем увеличит ее, а затем вернет копию
  • Preincrement увеличит значение, а затем вернет оригинал

Таким образом (если вы не работаете с простыми вещами, такими как целые числа) предварительное увеличение происходит быстрее.

Это зависит. В наивном компиляторе preincrement будет быстрее. В псевдокоде вот что делает каждый из них:

preincrement() {
  val = val + 1;
  return val;
}

postincrement() {
 tmp = val; // take a temporary copy of the old value
 val = val + 1;
 return tmp;
}

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

При работе с непримитивными типами: ++iter всегда будет более эффективным.

Причина, по которой ++ iter более эффективен, сводится к работе, которую каждый из них должен выполнить, чтобы получить возвращаемое значение.Используется ли возвращаемое значение на самом деле или нет, не имеет значения.

Разница:

  • ++iter возвращает ссылка на самого себя, так что временная копия не требуется.(увеличение, возвращает ссылку на собственное значение)

  • iter++ возвращает временную копию переменной (создать временную переменную со старым значением, увеличить, вернуть временную переменную)

    _Myt _Tmp = *this;
    ++*this;
    return (_Tmp);
    

Вы также могли бы попробовать задать один из этих похожих вопросов: здесь или здесь или здесь или здесь.Однако они не совсем одинаковы, поскольку не применимы к итераторам.

Я почти уверен, что они сводятся к одному и тому же в машинном коде, просто в другом порядке. Я бы сказал, что они одинаковы, но я бы порекомендовал вам написать быстрое тестовое приложение для проверки.

Предварительное увеличение, как правило, лучше, если у вас нет особой необходимости в последующем увеличении.

Однако это специфическая для компилятора вещь. Большинство современных компиляторов создают меньше операций для записи префикса. Однако при перегрузке методов класса это не всегда оптимизируется, поскольку зависит от того, как реализован класс.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top