为什么一项任务比另一项更快?

Dav*_*log 1 c assembly

我听到很多人说

int a = 0;
a += 10;
Run Code Online (Sandbox Code Playgroud)

比...更快

int a = 0;
a = a + 10;
Run Code Online (Sandbox Code Playgroud)

这是为什么?我用gdb调试它,它绝对是相同的指令.

gdb:

第一

(gdb) list
1   int main()
2   {
3       int counter = 0;
4       counter = counter + 10;
5       return 0;
6   }
(gdb) disassemble main
Dump of assembler code for function main:
   0x00000000004004cc <+0>: push   %rbp
   0x00000000004004cd <+1>: mov    %rsp,%rbp
   0x00000000004004d0 <+4>: movl   $0x0,-0x4(%rbp)
   0x00000000004004d7 <+11>:    addl   $0xa,-0x4(%rbp)
=> 0x00000000004004db <+15>:    mov    $0x0,%eax
   0x00000000004004e0 <+20>:    pop    %rbp
   0x00000000004004e1 <+21>:    retq   
End of assembler dump.
Run Code Online (Sandbox Code Playgroud)

第二

(gdb) list
1   int main()
2   {
3       int counter = 0;
4       counter += 10;
5       return 0;
6   }

(gdb) disassemble main
Dump of assembler code for function main:
   0x00000000004004cc <+0>: push   %rbp
   0x00000000004004cd <+1>: mov    %rsp,%rbp
   0x00000000004004d0 <+4>: movl   $0x0,-0x4(%rbp)
   0x00000000004004d7 <+11>:    addl   $0xa,-0x4(%rbp)
=> 0x00000000004004db <+15>:    mov    $0x0,%eax
   0x00000000004004e0 <+20>:    pop    %rbp
   0x00000000004004e1 <+21>:    retq   
End of assembler dump.
Run Code Online (Sandbox Code Playgroud)

那么为什么"(变量)+ =(值)"比"(变量)=(变量)+(值)"更快?

Car*_*rum 8

它并不快.如您所见,生成的程序集完全相同.无论谁告诉你一个人,编造故事的速度要快得多.

  • 即使在C++中,任何现代编译器都会"做正确的事情".无论如何,问题标记为C,OP证明它们是相同的,那就是结束...... (3认同)
  • `a`和`b`是`int`s.无论如何,这个C++谈话与这个问题无关. (2认同)

ugo*_*ren 6

正如其他人所说,在这种情况下并不重要.但是,有一些相似但非常不同的情况:

int *f(void);
(*f()) = (*f()) + 1;
(*f()) += 1;
Run Code Online (Sandbox Code Playgroud)

在第2行,f()被调用两次,在第3行只调用一次.

int * volatile *p;
**p = **p + 1;
**p += 2;
Run Code Online (Sandbox Code Playgroud)

在第二行中,编译器将读取*p两次,假设它可能在访问之间发生变化(并且您将读取一个地方,另一个地方写入).在第3个,它会读取*p一次并增加这个地方.

如果你觉得顽皮:

#define a *f()
int a;
a = a + 1;
a++;
Run Code Online (Sandbox Code Playgroud)

看起来几乎与问题完全一样,但表现得像我的第一个例子.