[C++] 返回值优化
什么是返回值优化?
返回值优化(Return Value Optimization, RVO)是C++编译器的一种优化技术,用于减少不必要的对象拷贝,特别是在函数返回临时对象的场景中。RVO 可以显著提高程序性能,并减少临时对象的生成和析构操作。
在C++中,函数返回值通常会涉及临时对象的创建和销毁。例如,当函数返回一个对象时,通常会创建一个临时对象来存储返回值,然后将其拷贝到接收返回值的变量中。返回值优化(RVO)是编译器的一种优化技术,它避免了这些临时对象的拷贝操作。
RVO的工作机制
通常情况下,返回一个对象的过程涉及两步:
- 创建并初始化一个临时对象(可能是函数内的局部对象)。
- 将这个临时对象拷贝或移动到调用者提供的目标位置。
RVO通过直接在目标位置构造返回的对象,跳过了临时对象的创建,从而避免了拷贝或移动操作。
例子(无RVO vs. 有RVO)
没有RVO时:
1 |
|
在上述代码中,createObject()
函数返回一个局部对象 obj
,在没有RVO的情况下:
- 首先构造局部对象
obj
。 - 然后调用拷贝构造函数将
obj
拷贝到一个临时对象(用来保存返回值)。 - 最后将这个临时对象拷贝到
newObj
中。
因此,会涉及两次拷贝构造调用,这样的拷贝是性能上的浪费。
有RVO时:
1 |
|
在启用RVO的情况下,编译器会跳过临时对象的创建,直接在 newObj
的内存位置上构造 obj
,避免了不必要的拷贝操作。
RVO的类型
- 命名返回值优化(Named Return Value Optimization, NRVO):NRVO是RVO的一种形式,发生在返回值是命名的局部变量时。例如,函数返回一个命名的局部对象,编译器会直接在调用者的内存空间中构造该对象,而不是先创建一个临时对象。
- 标准RVO:标准RVO发生在返回一个未命名的临时对象时。例如,函数返回一个临时构造的对象,而不是局部变量。这种优化在C++17后是强制执行的,不再依赖于编译器是否选择进行优化。
C++17 中的强制RVO
从C++17开始,标准RVO成为强制行为,编译器必须执行返回值优化,不再需要拷贝或移动临时对象。例如:
1 |
|
在C++17之前,编译器可能会选择不进行优化,但从C++17开始,编译器必须直接在目标位置构造返回的对象,从而完全消除了临时对象和拷贝构造的开销。
总结
- RVO(返回值优化)是一种编译器优化技术,可以在函数返回对象时避免不必要的临时对象拷贝。
- NRVO(命名返回值优化)是RVO的一种形式,应用于返回命名的局部变量。
- C++17中强制执行了RVO,编译器必须优化返回临时对象的场景,进一步提高了程序效率。
[C++] 返回值优化
https://erlsrnby04.github.io/2024/09/22/C-返回值优化/