Imo*_*lis -1 c math performance increment addition
例:
a : ++i;
b : i++;
c : i += 1;
d : i = i + 1;
Run Code Online (Sandbox Code Playgroud)
假设每个abcd被称为完全同步,其中一个将首先执行?
使用gcc 5.2编译这个程序:
#include<stdio.h>
int main()
{
int i = 0;
++i;
i++;
i += 1;
i = i + 1;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它给出了这个ASM:
main:
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], 0
add DWORD PTR [rbp-4], 1 #++i
add DWORD PTR [rbp-4], 1 #i++
add DWORD PTR [rbp-4], 1 #i += 1
add DWORD PTR [rbp-4], 1 #i = i + 1
mov eax, 0
pop rbp
ret
Run Code Online (Sandbox Code Playgroud)
这意味着使用gcc 5.2,它的执行速度完全相同.
对于从4.4.7到5.2的版本,它似乎是相同的.
在这个特定的例子中,所有四个表达式都具有完全相同的外部可观察结果,因此有能力的编译器应该为它们生成完全相同的代码.
编译器不会盲目地读取代码并为每个语句生成一些指令,编译器会根据标准推断代码的结果,并生成整个程序根据需要运行所需的代码.因此,询问关于单个陈述的表现问题几乎总是毫无意义.让我举个例子:
void foo(unsigned int a, unsigned int b) { unsigned int i = a * b; }
void bar(unsigned int a, unsigned int b) { unsigned int i = a + b; }
Run Code Online (Sandbox Code Playgroud)
哪一个更快?功能foo还是bar?许多人会说"当然乘法更慢",但很可能答案是:两者都同样快,因为非常简单的死存储优化会看到没有用i,所以不需要计算它,所以编译器可以优化函数一无所获.我们来试试吧:
$ cat > foo.c
void foo(unsigned int a, unsigned int b) { unsigned int i = a * b; }
void bar(unsigned int a, unsigned int b) { unsigned int i = a + b; }
$ cc -S -fomit-frame-pointer -O2 foo.c
$ cat foo.s
[... I edited out irrelevant spam to make this more readable ...]
_foo: ## @foo
retq
_bar: ## @bar
retq
Run Code Online (Sandbox Code Playgroud)
两个函数中唯一的指令retq只是从函数返回.