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
и ++
должны быть в два раза быстрее.
Многие люди концентрируются на такой низкоуровневой оптимизации, как будто это оптимизация. Я полагаю, вы знаете, что это гораздо больший предмет.