C中的一些好玩的事(一)转
我有如下三行代码:
1
2
3
4
|
int a = 8;
int ret = a/2;
ret = a >> 1; |
现在讨论上面两种实现除以2方式的性能,我们有如下伪汇编代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
int a = 8;
013B143E mov dword ptr [a],8 \ 将8赋值为变量a int ret = a/2;
013B1445 mov eax,dword ptr [a] \ 将a的值赋值给eax 013B1448 cdq \ 双字转换为4 字(把EAX 中的字的符号扩展到EDX 中去) 013B1449 sub eax,edx \ 用eax减去edx,并将结果存入eax 013B144B sar eax,1 \ 将eax算术右移一位 013B144D mov dword ptr [ret],eax \ 将eax的值写入到ret地址中 ret = a >> 1;
013B1450 mov eax,dword ptr [a] \ 将a的值赋值给eax 013B1453 sar eax,1 \ 将eax算术右移一位 013B1455 mov dword ptr [ret],eax \ 将eax的值写入到ret地址中 |
结论很清楚,通过移位能得到更好的效率。
在a等于负数的时候,以上两种方式可能会得到不同的结果。
如果a == -3,那么a/2 == –2;但是 a>>1会等于-1。
我有如下三行代码:
1
2
3
4
|
int a = 8;
int ret = a/2;
ret = a >> 1; |
现在讨论上面两种实现除以2方式的性能,我们有如下伪汇编代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
int a = 8;
013B143E mov dword ptr [a],8 \ 将8赋值为变量a int ret = a/2;
013B1445 mov eax,dword ptr [a] \ 将a的值赋值给eax 013B1448 cdq \ 双字转换为4 字(把EAX 中的字的符号扩展到EDX 中去) 013B1449 sub eax,edx \ 用eax减去edx,并将结果存入eax 013B144B sar eax,1 \ 将eax算术右移一位 013B144D mov dword ptr [ret],eax \ 将eax的值写入到ret地址中 ret = a >> 1;
013B1450 mov eax,dword ptr [a] \ 将a的值赋值给eax 013B1453 sar eax,1 \ 将eax算术右移一位 013B1455 mov dword ptr [ret],eax \ 将eax的值写入到ret地址中 |
结论很清楚,通过移位能得到更好的效率。
在a等于负数的时候,以上两种方式可能会得到不同的结果。
如果a == -3,那么a/2 == –2;但是 a>>1会等于-1。