Я могу вспомнить ситуацию, когда постфикс медленнее, чем приращение префикса:
Представьте себе, что процессор с регистром A
используется в качестве аккумулятора, и это единственный регистр, используемый во многих инструкциях (некоторые маленькие микроконтроллеры действительно таковы).
Теперь представьте следующую программу и ее перевод в гипотетическую сборку:
Приращение префикса:
a = ++b + c;
; increment b
LD A, [&b]
INC A
ST A, [&b]
; add with c
ADD A, [&c]
; store in a
ST A, [&a]
Постфиксный прирост:
a = b++ + c;
; load b
LD A, [&b]
; add with c
ADD A, [&c]
; store in a
ST A, [&a]
; increment b
LD A, [&b]
INC A
ST A, [&b]
Обратите внимание, как значение b
было принудительно перезагружено. При увеличении префикса компилятор может просто увеличивать значение и продолжать использовать его, возможно, избегая его перезагрузки, поскольку желаемое значение уже находится в регистре после увеличения. Однако с постфиксным инкрементом компилятору приходится иметь дело с двумя значениями, одним старым и одним увеличенным значением, которое, как я покажу выше, приводит к еще одному доступу к памяти.
Конечно, если значение приращения не используется, например, один оператор i++;
, компилятор может (и делает) просто генерировать инструкцию приращения независимо от использования постфикса или префикса.
В качестве примечания хочу отметить, что выражение, в котором есть b++
, не может быть просто преобразовано в выражение с ++b
без каких-либо дополнительных усилий (например, путем добавления - 1
). Таким образом, сравнение двух, если они являются частью какого-либо выражения, не совсем корректно. Часто, когда вы используете b++
внутри выражения, вы не можете использовать ++b
, поэтому даже если бы ++b
были потенциально более эффективными, это было бы просто неправильно. Исключение, конечно, если выражение требует его (например, a = b++ + 1;
, который можно изменить на a = ++b;
).