Почему n++ выполняется быстрее, чем n=n+1?
на языке C, почему n++ выполнить быстрее, чем n=n+1?  
(int n=...;  n++;)
(int n=...;  n=n+1;)
наш инструктор задал этот вопрос в сегодняшнем классе. (это не домашнее задание)
10 ответов
это было бы верно, если вы работаете на "каменного века" компилятора...
в случае "каменного века":++n быстрее n++ быстрее n=n+1 
Машина обычно имеет increment x а также add const to x
- в случае 
n++, у вас будет только 2 доступа к памяти (чтение n, inc n, запись n ) - в случае 
n=n+1, у вас будет 3 доступа к памяти (читать n, читать const, добавить n и const, напишите n) 
но сегодняшний компилятор автоматически преобразует n=n+1 to ++n, и это сделает больше, чем вы можете себе представить!!
также на сегодняшних неработающих процессорах-несмотря на случай "каменного века" компилятор - среда выполнения не может быть затронуты на всех во многих случаях!!
на GCC 4.4.3 для x86, с и без оптимизации, они компилируются в тот же самый код сборки и, таким образом, занимают столько же времени для выполнения. Как вы можете видеть в сборке, GCC просто преобразует n++ на n=n+1, затем оптимизирует его в одну инструкцию add (в-O2).
предложение вашего инструктора, что n++ быстрее применяется только к очень старым, не оптимизирующим компиляторам, которые не были достаточно умными, чтобы выбрать обновление на месте инструкции для n = n + 1. Эти компиляторы устарели в мире ПК в течение многих лет, но все еще могут быть найдены для странных проприетарных встроенных платформ.
C код:
int n;
void nplusplus() {
    n++;
}
void nplusone() {
    n = n + 1;
}
сборка вывода (без оптимизации):
    .file   "test.c"
    .comm   n,4,4
    .text
.globl nplusplus
    .type   nplusplus, @function
nplusplus:
    pushl   %ebp
    movl    %esp, %ebp
    movl    n, %eax
    addl    , %eax
    movl    %eax, n
    popl    %ebp
    ret
    .size   nplusplus, .-nplusplus
.globl nplusone
    .type   nplusone, @function
nplusone:
    pushl   %ebp
    movl    %esp, %ebp
    movl    n, %eax
    addl    , %eax
    movl    %eax, n
    popl    %ebp
    ret
    .size   nplusone, .-nplusone
    .ident  "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
    .section    .note.GNU-stack,"",@progbits
выходная сборка (с оптимизацией-O2):
    .file   "test.c"
    .text
    .p2align 4,,15
.globl nplusplus
    .type   nplusplus, @function
nplusplus:
    pushl   %ebp
    movl    %esp, %ebp
    addl    , n
    popl    %ebp
    ret
    .size   nplusplus, .-nplusplus
    .p2align 4,,15
.globl nplusone
    .type   nplusone, @function
nplusone:
    pushl   %ebp
    movl    %esp, %ebp
    addl    , n
    popl    %ebp
    ret
    .size   nplusone, .-nplusone
    .comm   n,4,4
    .ident  "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
    .section    .note.GNU-stack,"",@progbits
компилятор оптимизирует n + 1 в небытие.
Вы имеете в виду n = n + 1?
Если это так, они будут компилироваться в идентичную сборку. (Предполагая, что оптимизация включена и что это операторы, а не выражения)
кто говорит, что это так? Ваш компилятор оптимизирует все это, действительно, делая это спорным вопросом.
современные компиляторы должны уметь распознавать обе формы как эквивалентные и преобразовывать их в формат, который лучше всего работает на вашей целевой платформе.  Существует одно исключение из этого правила: переменные обращения, которые имеют побочные эффекты.  Например, если n - это некоторый аппаратный регистр, сопоставленный с памятью, чтение из него и запись в него могут сделать больше, чем просто передача значения данных (чтение может очистить прерывание, например).  Вы бы использовали volatile ключевое слово, чтобы компилятор знал, что он должен быть осторожен в оптимизации доступа к n и в этом случае компилятор может генерировать другой код n++ (операция инкремента) и n = n + 1 (операции чтения, добавления и хранения).  Однако для нормальных переменных компилятор должен оптимизировать обе формы до одного и того же.
на самом деле нет. Компилятор внесет изменения, характерные для целевой архитектуры. Микро-оптимизации, как это часто имеют сомнительные преимущества, но, что важно, конечно, не стоит времени программиста.
на самом деле, причина в том, что оператор определяется по-разному для post-fix, чем для pre-fix.  ++n увеличит "n "и вернет ссылку на" n " в то время как n++ приращение "n" будет возвращать const копия "n".  Отсюда и фраза n = n + 1 будет более эффективным.  Но я должен согласиться с вышеприведенными плакатами.  Хорошие компиляторы должны оптимизировать неиспользуемый объект return.
на языке C побочный эффект n++ выражения по определению эквивалент побочного эффекта n = n + 1 выражение. Поскольку ваш код полагается только на побочные эффекты, сразу очевидно, что правильный ответ заключается в том, что эти выражения всегда имеют точно эквивалентную производительность. (Независимо от каких-либо настроек оптимизации в компиляторе, кстати, поскольку проблема не имеет абсолютно никакого отношения к какой-либо оптимизации.)
никакого практического различия в производительность этих выражений возможна только в том случае, если компилятор намеренно (и злонамеренно!) пытается ввести это расхождение. Но в этом случае он может пойти в любом случае, конечно, т. е. в любом случае автор компилятора хотел его исказить.
Я думаю, что это больше похоже на аппаратное, а не программное обеспечение... Если я правильно помню, в старых процессорах n=n+1 требует двух местоположений памяти, где ++n-это просто команда микроконтроллера... Но я сомневаюсь, что это применимо к современной архитектуре...
все это зависит от директив компилятора/процессора/компиляции. Поэтому делать какие-либо предположения "что быстрее вообще" - не очень хорошая идея.