x=x+1 vs. x +=1

25,769

Solution 1

From the MSDN library for +=:

Using this operator is almost the same as specifying result = result + expression, except that result is only evaluated once.

So they are not identical and that is why x += 1 will be more efficient.

Update: I just noticed that my MSDN Library link was to the JScript page instead of the VB page, which does not contain the same quote.

Therefore upon further research and testing, that answer does not apply to VB.NET. I was wrong. Here is a sample console app:

Module Module1

Sub Main()
    Dim x = 0
    Console.WriteLine(PlusEqual1(x))
    Console.WriteLine(Add1(x))
    Console.WriteLine(PlusEqual2(x))
    Console.WriteLine(Add2(x))
    Console.ReadLine()
End Sub

Public Function PlusEqual1(ByVal x As Integer) As Integer
    x += 1
    Return x
End Function

Public Function Add1(ByVal x As Integer) As Integer
    x = x + 1
    Return x
End Function

Public Function PlusEqual2(ByVal x As Integer) As Integer
    x += 2
    Return x
End Function

Public Function Add2(ByVal x As Integer) As Integer
    x = x + 2
    Return x
End Function

End Module

IL for both PlusEqual1 and Add1 are indeed identical:

.method public static int32 Add1(int32 x) cil managed
{
.maxstack 2
.locals init (
    [0] int32 Add1)
L_0000: nop 
L_0001: ldarg.0 
L_0002: ldc.i4.1 
L_0003: add.ovf 
L_0004: starg.s x
L_0006: ldarg.0 
L_0007: stloc.0 
L_0008: br.s L_000a
L_000a: ldloc.0 
L_000b: ret 
}

The IL for PlusEqual2 and Add2 are nearly identical to that as well:

.method public static int32 Add2(int32 x) cil managed
{ 
.maxstack 2
.locals init (
    [0] int32 Add2)
L_0000: nop 
L_0001: ldarg.0 
L_0002: ldc.i4.2 
L_0003: add.ovf 
L_0004: starg.s x
L_0006: ldarg.0 
L_0007: stloc.0 
L_0008: br.s L_000a
L_000a: ldloc.0 
L_000b: ret 
}

Solution 2

I wrote a simple console app:

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

I disassembled it using Reflector and here's what i got:

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

They are the same.

Solution 3

they compile to the same, the second is just easier to type.

Solution 4

IMPORTANT:

The answers specifying evaluation are certainly correct in terms of what a += do, in general languages. But in VB.NET, I assume X specified in the OP is a variable or a property.


They'll probably compile to the same IL.

UPDATE (to address the probably controversy):

VB.NET is a specification of a programming language. Any compiler that conforms to what's defined in the spec can be a VB.NET implementation. If you edit the source code of the MS VB.NET compiler to generate crappy code for X += 1 case, you'll still conform to VB.NET spec (because it didn't say anything about how it's going to work. It just says the effect will be exactly the same, which makes it logical to generate the same code, indeed).

While the compiler is very very likely (and I feel it really does) generate the same code for both, but it's pretty complex piece of software. Heck, you can't even guarantee that a compiler generates the exact same code when the same code is compiled twice!

What you can feel 100% secure to say (unless you know the source code of the compiler intimately) is that a good compiler should generate the same code, performance-wise, which might or might not be the exact same code.

Solution 5

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

inc eax;

So you're right, after some compilation stage, the IL will be the same.

There's a whole class of questions like this that can be answered with "trust your optimizer."

The famous myth is that
x++;
is less efficient than
++x;
because it has to store a temporary value. If you never use the temporary value, the optimizer will remove that store.

Share:
25,769
Chad
Author by

Chad

Updated on May 02, 2020

Comments

  • Chad
    Chad almost 4 years

    I'm under the impression that these two commands result in the same end, namely incrementing X by 1 but that the latter is probably more efficient.

    If this is not correct, please explain the diff.

    If it is correct, why should the latter be more efficient? Shouldn't they both compile to the same IL?

    Thanks.