查看: 141|回复: 18
收起左侧

开发中关于三种参数传输的效率比较

[复制链接]

77

主题

3409

帖子

1万

积分

资深工程师

 楼主| 发表于 2017-4-22 12:26 | 显示全部楼层 |返回版面|阅读模式
如题,,这里主要说的是值传递,传指针,传地址三种方式的效率的。。先从函数调用角度去理解这三者区别的:

传值:   
  函数参数压栈的是参数的副本。   
  任何的修改是在副本上作用,没有作用在原来的变量上。  

  传指针:   
  压栈的是指针变量的副本。   
  当你对指针解指针操作时,其值是指向原来的那个变量,所以对原来变量操作。  

  传引用:   
  压栈的是引用的副本。由于引用是指向某个变量的,对引用的操作其实就是对他指向的变量的操作。


77

主题

3409

帖子

1万

积分

资深工程师

 楼主| 发表于 2017-4-22 12:28 | 显示全部楼层 |返回版面
三者在开发中的选用的比较的:
1. 从功能上。按值传递在传递的时候,实参被复制了一份,然后在函数体内使用,函数体内修改参数变量时修改的是实参的一份拷贝,而实参本身是没有改变的,所以如果想在调用的函数中修改实参的值,使用值传递是不能达到目的的,这时只能使用引用或指针传递。例如,要实现两个数值交换。
void swap(int a int b)
void main(){
int a=1 b=2
swap(a b)
}
这样,在main()函数中的a b值实际上并没有交换,如果想要交换只能使用指针传递或引用传递,如:
void swap(int *pa int *pb)

void swap(int& ra int& rb)

77

主题

3409

帖子

1万

积分

资深工程师

 楼主| 发表于 2017-4-22 12:30 | 显示全部楼层 |返回版面
2.从传递效率上。这里所说传递效率,是说调用被调函数的代码将实参传递到被调函数体内的过程,正如上面代码中,这个过程就是函数main()中的a b传递到函数swap()中的过程。这个效率不能一概而论。对于内建的int char short long float等4字节或以下的数据类型而言,实际上传递时也只需要传递1-4个字节,而使用指针传递时在32位cpu中传递的是32位的指针,4个字节,都是一条指令,这种情况下值传递和指针传递的效率是一样的,而传递double long long等8字节的数据时,在32位cpu中,其传值效率比传递指针要慢,因为8个字节需要2次取完。而在64位的cpu上,传值和传址的效率是一样的。再说引用传递,这个要看编译器具体实现,引用传递最显然的实现方式是使用指针,这种情况下与指针的效率是一样的,而有些情况下编译器是可以优化的,采用直接寻址的方式,这种情况下,效率比传值调用和传址调用都要快,与上面说的采用全局变量方式传递的效率相当。
再说自定义的数据类型,class struct定义的数据类型。这些数据类型在进行传值调用时生成临时对象会执行构造函数,而且当临时对象销毁时会执行析构函数,如果构造函数和析构函数执行的任务比较多,或者传递的对象尺寸比较大,那么传值调用的消耗就比较大。这种情况下,采用传址调用和采用传引用调用的效率大多数下相当,正如上面所说,某些情况下引用传递可能被优化,总体效率稍高于传址调用。

77

主题

3409

帖子

1万

积分

资深工程师

 楼主| 发表于 2017-4-22 12:31 | 显示全部楼层 |返回版面
3. 从执行效率上讲。这里所说的执行效率,是指在被调用的函数体内执行时的效率。因为传值调用时,当值被传到函数体内,临时对象生成以后,所有的执行任务都是通过直接寻址的方式执行的,而指针和大多数情况下的引用则是以间接寻址的方式执行的,所以实际的执行效率会比传值调用要低。如果函数体内对参数传过来的变量进行操作比较频繁,执行总次数又多的情况下,传址调用和大多数情况下的引用参数传递会造成比较明显的执行效率损失。
综合2、3两种情况,具体的执行效率要结合实际情况,通过比较传递过程的资源消耗和执行函数体消耗之和来选择哪种情况比较合适。而就引用传递和指针传递的效率上比,引用传递的效率始终不低于指针传递,所以从这种意义上讲,在c++中进行参数传递时优先使用引用传递而不是指针。

77

主题

3409

帖子

1万

积分

资深工程师

 楼主| 发表于 2017-4-22 12:31 | 显示全部楼层 |返回版面
4. 从类型安全上讲。值传递与引用传递在参数传递过程中都执行强类型检查,而指针传递的类型检查较弱,特别地,如果参数被声明为 void ,那么它基本上没有类型检查,只要是指针,编译器就认为是合法的,所以这给bug的产生制造了机会,使程序的健壮性稍差,如果没有必要,就使用值传递和引用传递,最好不用指针传递,更好地利用编译器的类型检查,使得我们有更少的出错机会,以增加代码的健壮性。

77

主题

3409

帖子

1万

积分

资深工程师

 楼主| 发表于 2017-4-22 12:32 | 显示全部楼层 |返回版面
5. 从参数检查上讲。一个健壮的函数,总会对传递来的参数进行参数检查,保证输入数据的合法性,以防止对数据的破坏并且更好地控制程序按期望的方向运行,在这种情况下使用值传递比使用指针传递要安全得多,因为你不可能传一个不存在的值给值参数或引用参数,而使用指针就可能,很可能传来的是一个非法的地址(没有初始化,指向已经delete掉的对象的指针等)。所以使用值传递和引用传递会使你的代码更健壮,具体是使用引用还是使用,最简单的一个原则就是看传递的是不是内建的数据类型,对内建的数据类型优先使用值传递,而对于自定义的数据类型,特别是传递较大的对象,那么请使用引用传递。

77

主题

3409

帖子

1万

积分

资深工程师

 楼主| 发表于 2017-4-22 12:33 | 显示全部楼层 |返回版面
6. 从灵活性上。无疑,指针是最灵活的,因为指针除了可以像值传递和引用传递那样传递一个特定类型的对象外,还可以传递空指针,不传递任何对象。指针的这种优点使它大有用武之地,比如标准库里的time( )函数,你可以传递一个指针给它,把时间值填到指定的地址,你也可以传递一个空指针而只要返回值。

77

主题

3409

帖子

1万

积分

资深工程师

 楼主| 发表于 2017-4-22 12:34 | 显示全部楼层 |返回版面
讲了这么多的,三种传递方式的大家还是需要根据实际的情况灵活使用的。

28

主题

1233

帖子

3709

积分

中级工程师

发表于 2017-4-22 13:52 | 显示全部楼层 |返回版面
这三种参数传递的区分很明显的了

28

主题

1233

帖子

3709

积分

中级工程师

发表于 2017-4-22 13:53 | 显示全部楼层 |返回版面
我们一般用的最多的就是直接值传递的

25

主题

1215

帖子

3649

积分

中级工程师

发表于 2017-4-22 17:03 | 显示全部楼层 |返回版面
smilingangel 发表于 2017-4-22 12:28
三者在开发中的选用的比较的:
1. 从功能上。按值传递在传递的时候,实参被复制了一份,然后在函数体内使用 ...

这个注意各自的写法区别的

25

主题

1215

帖子

3649

积分

中级工程师

发表于 2017-4-22 17:04 | 显示全部楼层 |返回版面
smilingangel 发表于 2017-4-22 12:32
5. 从参数检查上讲。一个健壮的函数,总会对传递来的参数进行参数检查,保证输入数据的合法性,以防止对数 ...

在执行效率上,,传值函数要快很多的。

22

主题

1245

帖子

3735

积分

中级工程师

发表于 2017-4-27 22:13 | 显示全部楼层 |返回版面
这个经常开发程序的需要多关注

22

主题

1245

帖子

3735

积分

中级工程师

发表于 2017-4-27 22:14 | 显示全部楼层 |返回版面
三种参数传递的方式方向及效率的都差别很大的

25

主题

850

帖子

2560

积分

初级工程师

发表于 2017-4-29 10:01 | 显示全部楼层 |返回版面
smilingangel 发表于 2017-4-22 12:30
2.从传递效率上。这里所说传递效率,是说调用被调函数的代码将实参传递到被调函数体内的过程,正如上面代码 ...

这么说,引用传递效率最高的?
     

0

主题

11

帖子

43

积分

实习生

发表于 2017-4-29 10:20 | 显示全部楼层 |返回版面
我只知道指针的效率高

86

主题

3950

帖子

1万

积分

资深工程师

发表于 2017-4-30 12:08 | 显示全部楼层 |返回版面
smilingangel 发表于 2017-4-22 12:31
3. 从执行效率上讲。这里所说的执行效率,是指在被调用的函数体内执行时的效率。因为传值调用时,当值被传 ...

执行效率上来讲,引用传递效率还是蛮高的

22

主题

1245

帖子

3735

积分

中级工程师

发表于 2017-5-7 16:22 | 显示全部楼层 |返回版面
这三种参数的传递英语需要注意的。

28

主题

1233

帖子

3709

积分

中级工程师

发表于 2017-5-7 16:25 | 显示全部楼层 |返回版面
smilingangel 发表于 2017-4-22 12:31
4. 从类型安全上讲。值传递与引用传递在参数传递过程中都执行强类型检查,而指针传递的类型检查较弱,特别 ...

执行安全上说,,值传递是最妥当的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

分享 快速回复 返回顶部 返回列表