备忘——变量交换的效率

来源:互联网 发布:淘宝图片尺寸 编辑:程序博客网 时间:2024/06/04 00:05

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


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_startprocmovl    (%rdi), %eaxmovl    (%rsi), %edxmovl    %edx, (%rdi)movl    %eax, (%rsi)ret.cfi_endproc

swap2:.LFB36:.cfi_startprocmovl    (%rsi), %eaxxorl    (%rdi), %eaxmovl    %eax, (%rdi)xorl    (%rsi), %eaxmovl    %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文件是怎样的……
        本着自己动手丰衣足食的原则,有兴趣的同学应该使用自己的机器亲自验证一下,而不仅仅局限于别人的结论……