两数通过异或运算来交换值的实际意义

有一个面试题是两数之间不通过第三个数进行交换,该题的标准答案是:

	a ^= b;
	b ^= a;
	a ^= b;

我一直在思考,为什么希望不通过第三个数来计算,好处到底是什么。为了研究清楚它的意义,我看了下反汇编代码

这个是异或交换的反汇编,共15条指令:

		a ^= b;
00007FF7C3A30065  mov         eax,dword ptr [b]  
00007FF7C3A30068  mov         ecx,dword ptr [a]  
00007FF7C3A3006B  xor         ecx,eax  
00007FF7C3A3006D  mov         eax,ecx  
00007FF7C3A3006F  mov         dword ptr [a],eax  
		b ^= a;
00007FF7C3A30072  mov         eax,dword ptr [a]  
00007FF7C3A30075  mov         ecx,dword ptr [b]  
00007FF7C3A30078  xor         ecx,eax  
00007FF7C3A3007A  mov         eax,ecx  
00007FF7C3A3007C  mov         dword ptr [b],eax  
		a ^= b;
00007FF7C3A3007F  mov         eax,dword ptr [b]  
00007FF7C3A30082  mov         ecx,dword ptr [a]  
00007FF7C3A30085  xor         ecx,eax  
00007FF7C3A30087  mov         eax,ecx  
00007FF7C3A30089  mov         dword ptr [a],eax 

这个是传统的通过temp来交换的反汇编,共6条指令:

		temp = a;
00007FF7C3A300DC  mov         eax,dword ptr [a]  
00007FF7C3A300DF  mov         dword ptr [temp],eax  
		a = b;
00007FF7C3A300E5  mov         eax,dword ptr [b]  
00007FF7C3A300E8  mov         dword ptr [a],eax  
		b = temp;
00007FF7C3A300EB  mov         eax,dword ptr [temp]  
00007FF7C3A300F1  mov         dword ptr [b],eax  

从指令数量上看,异或交换并不占有优势。我写了个大循环代码测试

	int a = 0x11, b = 0x110;
	const int swap_times = 1e8;

	ULONGLONG m;
	m = GetTickCount64();
	for (size_t i = 0; i < swap_times; i++)
	{
		a ^= b;
		b ^= a;
		a ^= b;
	}
	printf("异或交换,执行时间%llu毫秒\n", GetTickCount64() - m);

	int temp;
	m = GetTickCount64();
	for (size_t i = 0; i < swap_times; i++)
	{
		temp = a;
		a = b;
		b = temp;
	}
	printf("中间变量交换,执行时间%llu毫秒\n", GetTickCount64() - m);

输出为:

异或交换,执行时间640毫秒
中间变量交换,执行时间313毫秒

看来异或交换时间上没有优势。从汇编代码上可以看出,它多用了一个寄存器ecx来取代栈上的中间变量temp,栈的功能是存储,栈空间是有限的,而寄存器是内存空间与逻辑运算单元之间的桥梁,不充当存储作用,也不存在空间占用的概念。所以我得到的结论是,异或交换的思想,就是用时间来换取空间

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值