Если вы прибегали к использованию циклов for
, то скорее всего, вы использовали i++
для инкремента переменной вашего цикла. А задумывались ли вы когда-то, почему вы используете именно такую конструкцию для инкремента?
Очевидно, что результатом i++
будет значение, которое на один больше от i
. Однако это можно реализовать по-разному: ++i
, i++
или даже i = i + 1
.
В этой небольшой статье я разберу два способа инкрементации (++i
, i++
) переменной цикла, а также расскажу, почему первый способ гораздо лучше второго.
Post-Increment, он же i++
, является самым популярным методом инкрементации переменной цикла.
Вот так выглядит этот метод в псевдокоде:
Поскольку оператор постинкрементного возврата должен возвращать исходное значение i
, а не увеличенное значение i + 1
, он должен хранить старую версию i
.
Это означает, что он использует память для хранения дополнительного значения, а поскольку в большинстве случаев мы не используем старую версию i
, то, можно сказать, что она просто бессмысленно занимает память.
Метод ++i
, или pre-increment, встречается гораздо реже и обычно используется программистами старой закалки в таких языках, как С или С++.
В псевдокоде это выглядит вот так:
Как вы уже заметили, здесь нам не нужно сохранять старое значение i
— мы можем просто инкрементировать его и вернуть. Такой подход более рационален и понятен в контексте циклов.
Можно также сказать, что, поскольку кэшированное значение i
никогда не используется в post-increment, компилятор просто оптимизирует эту строку, что делает оба оператора эквивалентными.
Действительно, это верно для примитивных типов, таких как integer. Однако для более сложных типов, таких как пользовательские типы или итераторы с перегруженной операцией +, компилятор не сможет безопасно оптимизировать операцию кэширования.
В общем, в большинстве случаев pre-incremental лучше или равноценно post-incremental, особенно в тех случаях, когда вам не нужно использовать предыдущее значение увеличиваемой переменной.