技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> 编程语言 --> C++ 传参时传内置类型时用传值(pass by value)方式效率较高

C++ 传参时传内置类型时用传值(pass by value)方式效率较高

浏览:1852次  出处信息

在《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: }
......

pass by value
从汇编代码可以看出,为啥内置类型作为函数参数传递时更高效。

另外关于C++函数调用过程压栈等汇编情况可参考 http://blog.csdn.net/dongtingzhizi/article/details/6680050


QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1