x=x+1 vs. x +=1

后端 未结 17 1100
独厮守ぢ
独厮守ぢ 2020-12-29 02:57

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 c

相关标签:
17条回答
  • 2020-12-29 03:05

    i thought the differences are due to the additional clock cycles used for memory references, but i turned out to be 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

    the instructions may be tranlated 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
    

    all turn out to be same :S its just some data that may be helpful. please comment!

    0 讨论(0)
  • 2020-12-29 03:06

    There is no difference in programmatic efficiency; just typing efficiency.

    0 讨论(0)
  • 2020-12-29 03:10

    At run time (at least with PERL) there is no difference. x+=1 is roughly .5 seconds faster to type than x = x+1 though

    0 讨论(0)
  • 2020-12-29 03:15

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

    Or maybe you should fix the question and specify that x is an integer or whatever.

    0 讨论(0)
  • 2020-12-29 03:16

    So many speculations! Even the conclusion with the Reflector thingy is not necessarily true because it can do optimizations while dissassembling.

    So why does none of you guys just have a look into the IL code? Have a look at the following C# programme:

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

    This code snippet compiles to:

    .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, it's in fact absolutely the same. And why is it? Because IL's purpose is to tell what to do, not how to. The optimization will be a job of the JIT compiler. Btw it's the same in VB.Net

    0 讨论(0)
  • 2020-12-29 03:17

    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 
    }
    
    0 讨论(0)
提交回复
热议问题