您的位置:首页 > 其它

值交换的两种方法及其效率分析

2004-08-25 20:34 429 查看
比如, 我们有两个数a, b要交换值, 我们一般通过这样的方式来达到目的:
int c;
c = a;
a = b;
b = c;
这样来达到交换a, b值的目的;
经常使用位操作的人, 或者会有这样的"高招":
a ^= b;
b ^= a;
a ^= b;
这样也能交换a, b的值, 而且还少用了一个中间参数.
现在我们看到了我们交换值的两种做法,到底哪一种更好呢?
呵呵, 看看反应, 我们将从汇编, 事实(时间)等各个角度来得出结果.
c = b;
mov eax,dword ptr [ebp-8]
mov dword ptr [ebp-0Ch],eax
b = a;
mov ecx,dword ptr [ebp-4]
mov dword ptr [ebp-8],ecx
a = c;
mov edx,dword ptr [ebp-0Ch]
mov dword ptr [ebp-4],edx
总共有六条汇编指令;
我们再看看后一种方法的汇编指令条数:
a ^= b;
mov eax,dword ptr [ebp-4]
xor eax,dword ptr [ebp-8]
mov dword ptr [ebp-4],eax
b ^= a;
mov ecx,dword ptr [ebp-8]
xor ecx,dword ptr [ebp-4]
mov dword ptr [ebp-8],ecx
a ^= b;
mov edx,dword ptr [ebp-4]
xor edx,dword ptr [ebp-8]
mov dword ptr [ebp-4],edx
怎么样? 后一种方法足足比前一种方法多了三条指令. 当然, 更直观的方法还是来点测试, 我们可以更显而易见的看到对比的结果, 而且这个结果也反映了一个比较普遍的策略.
第一种方法:
int a = 9;
int b = 8;
int c;

int nCount;
nCount = GetTickCount();
printf("Start time: %d/n", nCount);
for (int i = 0; i < 100000000; i++)
{
c = a;
a = b;
b = c;
}
nCount = GetTickCount();
printf("End time: %d/n", nCount);
结果是:
Start time: 38830024
End time: 38830395
用了371 ms.

第二种方法:
int a = 9;
int b = 8;

int nCount;
nCount = GetTickCount();
printf("Start time: %d/n", nCount);
for (int i = 0; i < 100000000; i++)
{
a ^= b;
b ^= a;
a ^= b;
}
nCount = GetTickCount();
printf("End time: %d/n", nCount);
结果是:
Start time: 38955024
End time: 38956125
用了1001ms.
两者的结果在大量重复操作下都呈现数量级上的差距了.
从这两种方法我们可以看出, 虽然第一种方法时间少, 但是其增加了一个变量的消耗, 第二种方法虽然时间多, 但是节省了一个变量的空间, 但是其损失的时间效率确是很客观的.
在某些场合, 时间很重要, 而存储器容量显然还没有到捉襟见肘的时候, 第一种方法显然是合适的, 它其实就是一个”空间换时间”的策略体现, 而且它更容易理解; 而第二种在理解上就比较不那么容易(你也许应该自己做一下逻辑运算才能知道它们确实交换了值:), 而且其时间损失是显而易见的(在电量比较极其的设备中, 这也是不能容忍的). 这也是第二中方法几乎快销声匿迹的原因了. 有一次在某论坛里看到有人拿出了第二种方法的代码, 还说是绝妙的三行代码, 呵呵.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: