我们写代码时,经常会碰到需要将两个数值变量互相交换的情况。
例如,要求交换变量A,B的值,写如下C代码。
情况1,利用临时变量T:
T = A; A = B; B = T;
情况2,不利用临时变量:
A ^= B; B ^= A; A ^= B;
那么,这两种实现方式的运行效率如何呢?
在Visual C++的编译环境里,如果不打开优化选项的话,C的代码会编译成如下代码。
情况1:
mov eax,A
mov T, eax
mov eax,B
mov A, eax
mov eax,T
mov B, eax
情况2:
mov eax,B
xor eax,A
mov A,eax
mov eax,A
xor eax,B
mov B,eax
mov eax,B
xor eax,A
mov A,eax
代码分析:
- 情况1有6个mov指令。
- 情况2也有6个mov指令,还有另外3个xor指令。
从代码长度的情况来看,情况1比较理想。
运行效率分析:
- 对代码进行100’000’000次左右的循环执行。
- 情况1的指令周期大约是204 clocks。
- 情况2的指令周期大约是602 clocks。
从运行时间效率的情况看,也是情况1比较理想。
看到这里,也许会有人提出,如果不用C实现呢?如果用更好的编译器呢?我们直接写汇编代码怎么样?
对,这是一个不错的想法,可以帮助我们直达问题的核心。于是我们开始试着直接写汇编代码。
情况3,不利用临时变量,占用3个寄存器:
mov eax,A
mov ebx,B
mov ecx,eax
mov eax,ebx
mov ebx,ecx
mov A,eax
mov B,ebx
代码分析:
- 7个mov指令。
运行效率分析:
- 100’000’000次左右的循环执行,指令周期大约是169 clocks。
情况4,不利用临时变量,占用2个寄存器:
mov eax,A
mov ebx,B
xor eax,ebx
xor ebx,eax
xor eax,ebx
mov A,eax
mov B,ebx
代码分析:
- 4个mov指令,3个xor指令。
运行效率分析:
- 100’000’000次左右的循环执行,指令周期大约是246 clocks。
情况5,不利用临时变量,占用2个寄存器,使用xchg指令:
mov eax,A
mov ebx,B
xchg eax,ebx
mov A,eax
mov B,ebx
代码分析:
- 4个mov指令,1个xchg指令。
运行效率分析:
- 100’000’000次左右的循环执行,指令周期大约是220 clocks。
情况6,不利用临时变量,