备忘——变量交换的效率

        今天在看汇编的时候,突然想起变量交换的问题来,记得原来老郭跟我说过一种变量交换的方法——异或。也不知道是怎么会突然产生这种怨念,于是就上网查了一下,这种方式究竟好不好,结果是这种“技巧”除了糊弄面试官以外,基本上没有啥实用性……


void swap(int *a, int *b)
{
	int tmp;
	tmp  = *a;
	*a = *b;
	*b = tmp;
}

void swap2(int *a, int *b)
{                                                                           
	*a ^= *b;
	*b ^= *a;
	*a ^= *b;
}

        

        上面的swap就是“正常思维”的交换,下面的swap2就是“异或思维”的交换,本着不相信一切牛鬼蛇神的原则,我是一定要看到汇编代码才肯罢休的……
        通过将C程序变为汇编程序以后(至少-O1优化),得到以下的汇编代码:


swap:                                                                       
.LFB35:
.cfi_startproc
movl    (%rdi), %eax
movl    (%rsi), %edx
movl    %edx, (%rdi)
movl    %eax, (%rsi)
ret
.cfi_endproc

swap2:
.LFB36:
.cfi_startproc
movl    (%rsi), %eax
xorl    (%rdi), %eax
movl    %eax, (%rdi)
xorl    (%rsi), %eax
movl    %eax, (%rsi)
xorl    %eax, (%rdi)
ret
.cfi_endproc

        即使看不懂汇编代码的同学至少也能看出来swap用了4行就解决了问题,而swap2用了6行才解决问题,并且在汇编的层面上,swap和swap2都没有使用“第三块内存”,虽然我们在swap中定义个了tmp变量,不过在优化的过程中,这个变量就被优化没了……
        这样,swap2的所有优势都荡然无存了,不仅没有节省内存空间,而且运算的步骤也更长……

        有兴趣的同学可以自己去看看不加任何编译优化是什么样的结果,其实即使不加任何编译优化,swap的汇编代码也比swap2要简洁的多……

#include <stdlib.h>
#include <stdio.h>

void print(int a, int b)
{
	printf("%d, %d", a, b);
}

void swap(int *a, int *b)
{
	int tmp;
	tmp = *a;
	*a = *b;
	*b = tmp;
}

void swap2(int *a, int *b)
{
	*a ^= *b;
	*b ^= *a;
	*a ^= *b;
}
/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  main
 *  Description:  
 * =====================================================================================
 */
int main(int argc, char *argv[])
{
	int a = 4;
	int b = 5;
	swap(&a, &b);
	print(a, b);

	return EXIT_SUCCESS;
}				/* ----------  end of function main  ---------- */

        以上这段代码是为了懒惰的同学准备的,将上面代码直接生成汇编:gcc -S code.c -O2,然后看看code.s文件是怎样的……
        本着自己动手丰衣足食的原则,有兴趣的同学应该使用自己的机器亲自验证一下,而不仅仅局限于别人的结论……

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值