导言
之前在阅读候捷老师的《深入探索C++对象模型》一书时,对于NRV优化操作这个编译器优化并还是特别的清楚。所以今天准备通过实际测试来深入了解一下这个NRV的编译器优化。
1 | #include <iostream> |
接下来我们将通过这个例子来深入了解NRV优化
不用NVR优化
1 | // g++ -o demo test.cpp -fno-elide-constructors |
在上述代码中,在成员函数get()函数中定义了一个Edge对象,然后将其作为返回值返回。如果按照调用copy construct,编译器会对代码进行一个扩张操作
- 首先加上一个额外参数,类型是类对象的一个引用,这个参数用来放置由copy construct 而得到的返回值。
- 在return命令之前安插一个copy construct调用操作,以便将欲传回的对象的内容当作上述新增参数的初值。
具体过程可以通过下面的伪代码来了解
1 | Edge get(Edge &_result) { |
在上述代码中,编译器的扩张操作,构造出了point。但是这个没用空构造的point根本就没有起到什么作用。对于编译器来说,这就会导致资源的浪费,拖慢运行速度。所以NRV优化操作就显的很有必要了。
使用NRV优化
1 | // g++ -o demo test.cpp |
编译器为了避免这个无意义的临时变量,编译器选择使用传入的参数(_ result)。对其直接进行构造,这样就避免了无意义的临时变量。具体操作参考如下伪代码
1 | Edge get(Edge &_result) { //额外参数作为引用参数介入函数 |
结束语
只有在显式定义copy construct 的时候,编译器才会激活NRV优化操作。对于普通的程序,是看不出NRV优化的好处,只有在庞大数据量时,NRV优化操作的优点才会显现出来。