备忘——变量交换的效率
来源:互联网 发布:淘宝图片尺寸 编辑:程序博客网 时间: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文件是怎样的……
本着自己动手丰衣足食的原则,有兴趣的同学应该使用自己的机器亲自验证一下,而不仅仅局限于别人的结论……
- 备忘——变量交换的效率
- 交换两个变量的值的效率的测试
- 交换两个变量效率问题
- 交换两个变量效率问题
- 交换变量A,B的代码运行效率分析
- 交换变量的值
- 交换变量的方法
- 交换变量的值
- 指针变量的交换
- 神奇的变量交换
- 不用临时变量交换两个变量的值——函数对象
- 一道面试题——不用中间变量交换两个整型变量的值
- C++ 不用临时变量交换两个变量的值——函数对象
- JAVA学习笔记——不临时变量交换两个变量的值
- JS——交换两个变量(不使用第三个变量的情况下)
- 指来指去——调用函数交换变量
- 指针练习——变量交换I
- C#练习——交换两个变量
- 邮件服务器端口协议
- 一个阿里巴巴码农的六年回眸
- Core Animation学习笔记一:CATransactions
- asp.net生成缩略图并支持文件上传实现代码
- Android NDK 初探
- 备忘——变量交换的效率
- ERP系统容灾方案析投入产出比例与维护管理成本分析
- Canny算子提取边缘Matlab源代码
- Django的模板系统
- gridview固定表头--纵向固定横向滚动
- ListView虚拟模式的使用
- Address already in use: JVM_Bind<null>:80 解决方案
- UNIX网络编程——SOCKET API和TCP STATE的对应关系_三次握手_四次挥手及TCP延迟确认
- Java加密技术(四)——非对称加密算法RSA