X = x + 1 по сравнению с x + = 1

У меня создается впечатление, что эти две команды приводят к одному и тому же концу, а именно к увеличению X на 1, но последнее, вероятно, более эффективно.

Если это неверно, объясните разницу.

Если это правильно, почему последний должен быть более эффективным? Разве они не должны скомпилировать тот же IL?

Спасибо.

Ответ 1

Из библиотека MSDN для + =:

Использование этого оператора почти совпадает с заданием результата result = result +, за исключением того, что результат оценивается только один раз.

Таким образом, они не идентичны, и именно поэтому x + = 1 будет более эффективным.

Обновление: Я только заметил, что моя ссылка на библиотеку MSDN была на странице JScript, а не на странице

Ответ 2

Я написал простое консольное приложение:

static void Main(string[] args)
{
    int i = 0;
    i += 1;
    i = i + 1;
    Console.WriteLine(i);
}

Я разобрал его с помощью Reflector, и вот что я получил:

private static void Main(string[] args)
{
    int i = 0;
    i++;
    i++;
    Console.WriteLine(i);
}

Они одинаковы.

Ответ 3

они скомпилируются в одно и то же, второе проще всего ввести.

Ответ 4

ВАЖНО:

Ответы, определяющие оценку, безусловно, правильны с точки зрения того, что делает +=, на общих языках. Но в VB.NET я предполагаю, что X, указанный в OP, является переменной или свойством.


Они, вероятно, скомпилируются с тем же IL.

ОБНОВЛЕНИЕ (для решения, вероятно, противоречия):

VB.NET - это спецификация языка программирования. Любой компилятор, который соответствует тому, что определено в спецификации, может быть реализацией VB.NET. Если вы отредактируете исходный код компилятора MS VB.NET для создания дрянного кода для случая X += 1, вы все равно будете соответствовать спецификации VB.NET(потому что он ничего не сказал о том, как он будет работать. говорит, что эффект будет таким же, что делает логичным генерировать тот же код, действительно).

В то время как компилятор очень вероятен (и я чувствую, что это действительно так) генерирует тот же код для обоих, но это довольно сложная часть программного обеспечения. Черт, вы не можете даже гарантировать, что компилятор генерирует тот же самый код, когда один и тот же код скомпилирован дважды!

Что вы можете почувствовать на 100% безопасным, чтобы сказать (если вы не знаете исходный код компилятора) - хороший компилятор должен генерировать один и тот же код, по производительности, который может быть или не быть точно таким же кодом.

Ответ 5

Так много спекуляций! Даже заключение с Reflector thingy не обязательно верно, потому что оно может делать оптимизации при разборке.

Итак, почему никто из вас, ребята, просто не заглядывает в код IL? Посмотрите следующую программу на С#:

static void Main(string[] args)
{
    int x = 2;
    int y = 3;
    x += 1;
    y = y + 1;
    Console.WriteLine(x);
    Console.WriteLine(y);
}

Этот фрагмент кода компилируется в:

.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 25 (0x19)
.maxstack 2
.locals init ([0] int32 x,
[1] int32 y)
// some commands omitted here


IL_0004: ldloc.0
IL_0005: ldc.i4.1
IL_0006: add
IL_0007: stloc.0


IL_0008: ldloc.1
IL_0009: ldc.i4.1
IL_000a: add
IL_000b: stloc.1


// some commands omitted here
}

Как вы можете видеть, это на самом деле абсолютно то же самое. И почему? Потому что цель IL - сказать, что делать, а не как. Оптимизация будет выполняться компилятором JIT. Btw это то же самое в VB.Net

Ответ 6

На x86, если x находится в регистре eax, они оба приведут к чему-то вроде

inc eax,

Итак, вы правы, после какой-то стадии компиляции IL будет тем же самым.

Здесь есть целый класс вопросов, на которые можно ответить, "доверяй своему оптимизатору".

Известный миф состоит в том, что х ++;
менее эффективен, чем ++ х;
потому что он должен хранить временное значение. Если вы никогда не используете временное значение, оптимизатор удалит это хранилище.

Ответ 7

Они могут быть одинаковыми в VB; они не обязательно одинаковы в C (откуда приходит оператор).

Ответ 8

  • Да, они ведут себя одинаково.
  • Нет, они, вероятно, одинаково эффективны. Оптимизаторы хороши в этом. Если вы хотите дважды проверить, напишите оптимизированный код и просмотрите его в отражателе.

Ответ 9

Оптимизатор, вероятно, дает тот же результат, если x - простой тип типа int или float.

Если бы вы использовали какой-либо другой язык (ограниченное знание VB здесь, вы можете перегрузить + =?), где x может быть одним большим объектом для отслеживания, первый создает и добавляет дополнительную копию, которая может составлять сотни мегабайт. Последнее не делает.

Ответ 10

совпадают.

x=x+1 

является математическим, но существует противоречие, тогда как

x+=1

нет и набирается свет.

Ответ 11

В С++ это зависит от того, какой тип данных x и как определяются операторы. Если x является экземпляром некоторого класса, вы можете получить совершенно разные результаты.

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

Ответ 12

Я думал, что различия связаны с дополнительными тактами, используемыми для ссылок на память, но я оказался неправ! не могу понять эту вещь сам

instruction type        example                      cycles

=============================================== ====================

ADD reg,reg             add ax,bx                       1
ADD mem,reg             add total, cx                   3
ADD reg,mem             add cx,incr                     2
ADD reg,immed           add bx,6                        1
ADD mem,immed           add pointers[bx][si],6          3
ADD accum,immed         add ax,10                       1

INC reg                 inc bx                          1
INC mem                 inc vpage                       3

MOV reg,reg             mov bp,sp                       1
MOV mem,reg             mov array[di],bx                1
MOV reg,mem             mov bx,pointer                  1
MOV mem,immed           mov [bx],15                     1
MOV reg,immed           mov cx,256                      1
MOV mem,accum           mov total,ax                    1
MOV accum,mem           mov al,string                   1
MOV segreg,reg16        mov ds,ax                       2, 3
MOV segreg,mem16        mov es,psp                      2, 3
MOV reg16,segreg        mov ax,ds                       1
MOV mem16,segreg        mov stack_save,ss               1
MOV reg32,controlreg    mov eax,cr0                     22
                        mov eax,cr2                     12
                        mov eax,cr3                     21, 46
                        mov eax,cr4                     14
MOV controlreg,reg32    mov cr0,eax                     4
MOV reg32,debugreg      mov edx,dr0                     DR0-DR3,DR6,DR7=11;
                                                        DR4,DR5=12 
MOV debugreg,reg32      mov dr0,ecx                     DR0-DR3,DR6,DR7=11;
                                                        DR4,DR5=12 

источник: http://turkish_rational.tripod.com/trdos/pentium.txt

инструкции могут быть транслированы как:

;for i = i+1   ; cycles
mov  ax,   [i]  ; 1
add  ax,   1    ; 1
mov  [i],  ax   ; 1

;for i += 1
; dunno the syntax of instruction. it should be the pointers one :S     

;for i++
inc  i          ; 3
;or
mov  ax,   [i]  ; 1
inc  ax         ; 1
mov  [i],  ax   ; 1

;for ++i
mov  ax,   [i]  ; 1
;do  stuff      ; matters not
inc  ax         ; 1
mov  [i],  ax   ; 1

все оказываются одинаковыми: S его просто некоторые данные, которые могут быть полезны. пожалуйста, прокомментируйте!

Ответ 13

Что-то стоит отметить, что + =, - =, * = и т.д. делают неявный листинг.

int i = 0;
i = i + 5.5; // doesn't compile.
i += 5.5; // compiles.

Ответ 14

Во время выполнения (по крайней мере, с PERL) разницы нет. x + = 1 примерно на 5 секунд быстрее, чем x = x + 1, хотя

Ответ 15

Нет никакой разницы в эффективности программ; просто набрав эффективность.

Ответ 16

Еще в начале 1980-х одна из действительно крутых оптимизаций компилятора Lattice C заключалась в том, что "x = x + 1;", "x + = 1;" и "x ++;" все они производят точно такой же машинный код. Если бы они могли это сделать, компилятор, написанный в этом тысячелетии, определенно сможет это сделать.

Ответ 17

Если x - простая целочисленная скалярная переменная, они должны быть одинаковыми.

Если x - большое выражение, возможно, с побочными эффектами, +=1 и ++ должны быть в два раза быстрее.

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