每一个了解C++语言的人,都明白函数参数可以传递引用,也可以传递实体。对于熟悉C++语言的人来说,传递引用与传递实体的区别也都明白,比如:
- 传递引用:类似于传递地址,不需要构建新的实例,如果修改它则实参被修改
- 传递实体:实参和形参是两个完全独立的实例,形参类似局部变量
- 大数据参数的传递,传递引用和传递实体的差别比较大,在如下的示例代码中,使用foo函数比较好,因为避免了在Stack上复制数据。
对于大数据参数而言,使用const Type& data是最优的传递方式。
-
小数据(基本数据类型和数据量不大的类型)参数的传递,两种传递方式差别不是特别大,那么究竟使用实体还是const引用比较好一些呢?示例程序如下:
粗略看来,都差不多,但细究起来,应该选择bar函数的实体传递方式,为什么呢?要弄明白二者有何差别,需要细细的把C++语句掰开来,窥视一下编译出来的汇编指令。
- 函数实体参数的访问指令
bar函数对参数的使用会被编译为如下汇编指令:
- 函数const引用的访问指令
foo函数对参数的使用会被编译为如下汇编指令:
在foo函数中,对于const&参数的使用是需要访问两次内存的(先从内存[ebp+8]中拿出地址放入eax,再从内存[eax]中拿出需要的数据)。由此看来使用bar函数而不使用foo函数也就明白了。另外,多访问一次内存,可能导致CPU的缓存不命中,导致较慢的读取内存操作,而数据从Stack里面直接读取,几乎是快速的从CPU缓存中读取的,无需访问外部内存。
- 函数实体参数的访问指令
所以对于简单数据,传递const引用就是典型的吃力不讨好的事儿,直接传递值就行了,还节省了敲代码的时间。