C++ 传参时传内置类型时用传值(pass by value)方式效率较高
浏览:1893次 出处信息
在《Effective C++》里提到对内置(C-like)类型在函数传参时pass by value比pass by reference更高效,当用OO的c++自定义类型(存在构造/析构等)pass by reference to const 更好,STL里的迭代器和函数对象是用C指针实现的,因此pass by value更好。至于为什么,下面的代码验证了下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | #include <iostream> using namespace std; int f(int i) { int r = i + 1; return r; } int g(const int & i) { int r = i + 1; return r; } int h(int * p) { int r = * p + 1; return r; } int inter(int * &p) { int r = * p + 1; return r; } int main() { int i = 0x11111111; f(i); g(i); h(&i); int * x = &i; r = inter(x); return 0; } |
用VS 2012 默认Debug配置下生成的汇编代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 4: int f(int i) 5: { 00F343D0 push ebp 00F343D1 mov ebp,esp 00F343D3 sub esp,0CCh 00F343D9 push ebx 00F343DA push esi 00F343DB push edi 00F343DC lea edi,[ebp-0CCh] 00F343E2 mov ecx,33h 00F343E7 mov eax,0CCCCCCCCh 00F343EC rep stos dword ptr es:[edi] 6: int r = i + 1; 00F343EE mov eax,dword ptr [i] //直接将i的值取出来给eax 00F343F1 add eax,1 //eax+1 00F343F4 mov dword ptr [r],eax 7: return r; 00F343F7 mov eax,dword ptr [r] 8: } 00F343FA pop edi 00F343FB pop esi 00F343FC pop ebx 00F343FD mov esp,ebp 00F343FF pop ebp 00F34400 ret |
后面的几个函数,只截取了关键代码了。
1 2 3 4 5 6 7 8 9 10 11 12 | 10: int g(const int &i) 11: { ...... 12: int r = i + 1; 00F3449E mov eax,dword ptr [i] // 跟传指针一样,取i的地址到eax 00F344A1 mov ecx,dword ptr [eax] // 将eax的值取出来 放到ecx中 00F344A3 add ecx,1 // ecx值+1 00F344A6 mov dword ptr [r],ecx 13: return r; 00F344A9 mov eax,dword ptr [r] 14: } ...... |
1 2 3 4 5 6 7 8 9 10 11 12 | 16: int h(int * p) 17: { ...... 18: int r = *p + 1; 00F3453E mov eax,dword ptr [p] // 取p的地址,让到eax中 00F34541 mov ecx,dword ptr [eax] //把eax的值取出来,让到ecx中 00F34543 add ecx,1 //exc的值+1 00F34546 mov dword ptr [r],ecx 19: return r; 00F34549 mov eax,dword ptr [r] 20: } ...... |
指针跟上面引用一样。
1 2 3 4 5 6 7 8 9 10 11 12 13 | 22: int inter(int * &p) 23: { ...... 24: int r = *p + 1; 01233DBE mov eax,dword ptr [p] //取传进参数(指针)的地址->eax 01233DC1 mov ecx,dword ptr [eax] //取参数指针的地址-->ecx, (是真正值的地址) 01233DC3 mov edx,dword ptr [ecx] //取ecx的内容->edx 01233DC5 add edx,1 //edx 值+1 01233DC8 mov dword ptr [r],edx 25: return r; 01233DCB mov eax,dword ptr [r] 26: } ...... |
另外关于C++函数调用过程压栈等汇编情况可参考 http://blog.csdn.net/dongtingzhizi/article/details/6680050
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
扫一扫订阅我的微信号:IT技术博客大学习
<< 前一篇:struct与class区别联系
文章信息
- 作者:tanglei 来源: tanglei's blog|唐磊的个人博客
- 标签: 传参
- 发布时间:2015-01-24 23:15:57
近3天十大热文
- [70] IOS安全–浅谈关于IOS加固的几种方法
- [67] Twitter/微博客的学习摘要
- [65] 如何拿下简短的域名
- [62] android 开发入门
- [61] find命令的一点注意事项
- [60] Go Reflect 性能
- [58] 流程管理与用户研究
- [57] 图书馆的世界纪录
- [56] Oracle MTS模式下 进程地址与会话信
- [56] 读书笔记-壹百度:百度十年千倍的29条法则