X = x + 1 compared to x + = 1

I get the impression that these two teams lead to the same end, namely increasing X by 1, but the latter is probably more efficient.

If this is not the case, explain the difference.

If this is correct, why should the latter be more effective? Shouldn't they compile the same IL?

Thank.

+29
performance operators
Apr 30 '09 at 17:15
source share
17 answers

From the MSDN library for + = :

Using this operator almost coincides with setting the result result = result +, except that the result is evaluated only once.

Thus, they are not identical, which is why x + = 1 will be more efficient.

Update: I just noticed that my link to the MSDN library was on a JScript page, not a page

+105
Apr 30 '09 at 17:25
source share

I wrote a simple console application:

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

I parsed it using Reflector, and here is what I got:

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

They are the same.

+25
Apr 30 '09 at 17:29
source share

they are compiled into the same thing, the second is easiest to enter.

+19
Apr 30 '09 at 17:17
source share

IMPORTANT:

The answers defining the assessment are certainly correct in terms of what += does in common languages. But in VB.NET, I assume that the X specified in the OP is a variable or property.




They are probably compiled with the same IL.

UPDATE (to resolve the likely contradiction):

VB.NET is a specification of a programming language. Any compiler that matches what is defined in the specification can be an implementation of VB.NET. If you edit the source code of the MS VB.NET compiler to create crappy code for the case X += 1 , you will still comply with the VB.NET specification (because it did not say anything about how it will work. Says that the effect will be same, which makes it logical to generate the same code, really).

While the compiler is very likely (and I feel this is true) it generates the same code for both, but this is a rather complicated piece of software. Hell, you cannot even guarantee that the compiler generates the same code when the same code is compiled twice!

What can you feel 100% safe to say (if you do not know the source code of the compiler) - a good compiler should generate the same code in terms of performance, which may or may not be exactly the same code.

+11
Apr 30 '09 at 17:17
source share

So much speculation! Even the conclusion with the Reflector thingy is not necessarily true, because it can do optimizations when disassembling.

So why don't any of you guys just peek into the IL code? See the following program in C #:

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

This piece of code compiles into:

.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
}

As you can see, this is actually exactly the same. And why? Because the purpose of IL is to say what to do, not how. Optimization will be performed by the JIT compiler. Btw is the same in VB.Net

+8
Apr 30 '09 at 18:03
source share

On x86, if x is in the eax register, they will both result in something like

inc eax,

So, you are right, after some stage of compilation, IL will be the same.

There is a whole class of questions that you can answer, "trust your optimizer."

A famous myth is that x ++;
less effective than ++ x;
because it has to store a temporary value. If you never use a temporary value, the optimizer will delete this storage.

+4
Apr 30 '09 at 17:24
source share

They may be the same in VB; they are not necessarily the same in C (where the operator comes from).

+2
Apr 30 '09 at 17:18
source share
  • Yes, they behave the same.
  • No, they are probably equally effective. Optimizers are good at this. If you want to double check, write the optimized code and view it in the reflector.
+2
Apr 30 '09 at 17:18
source share

The optimizer probably gives the same result if x is a simple int or float type.

If you used any other language (limited knowledge of VB here, you can overload + =?), Where x can be one large object to track, the first creates and adds an additional copy, which can be hundreds of megabytes. The latter does not.

+2
Apr 30 '09 at 17:19
source share

match.

 x=x+1 

is mathematical, but there is a contradiction, whereas

 x+=1 

no and light is gathering.

+2
Apr 30 '09 at 17:20
source share

In C ++, it depends on what data type x is and how operators are defined. If x is an instance of some class, you can get completely different results.

Or maybe you should fix the question and indicate that x is integer or any other.

+1
Apr 30 '09 at 18:56
source share

I thought the differences were due to the extra clocks used for memory references, but I was wrong! can't understand this thing myself

 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 

source: http://turkish_rational.tripod.com/trdos/pentium.txt

instructions can be translated as:

 ;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 

everyone turns out to be the same: S its just some data that may be useful. please comment!

+1
Apr 30 '09 at 18:57
source share

Something worth noting is that + =, - =, * =, etc. do implicit listing.

 int i = 0; i = i + 5.5; // doesn't compile. i += 5.5; // compiles. 
+1
May 01 '09 at 6:38
source share

There is no difference at run time (at least with PERL). x + = 1 is about 5 seconds faster than x = x + 1, although

0
Apr 30 '09 at 17:18
source share

There is no difference in the effectiveness of programs; just gaining efficiency.

0
Apr 30 '09 at 17:20
source share

Back in the early 1980s, one of the really cool Lattice C compiler optimizations was that "x = x + 1;", "x + = 1;" and "x ++;" they all produce exactly the same machine code. If they could do this, a compiler written in this millennium could definitely do it.

0
Apr 30 '09 at 17:24
source share

If x is a simple integer scalar variable, they must be the same.

If x is a large expression, possibly with side effects, +=1 and ++ should be twice as fast.

Many people concentrate on such low-level optimization as if it were optimization. I suppose you know that this is a much larger subject.

0
May 01 '09 at 11:51
source share



All Articles