For years, the Microsoft Visual C + + compiler has been trying to find newer technologies and optimizations to maximize the performance of your programs. This article describes how the Visual C + + compiler eliminates redundant copy constructors and destructors in different situations.
Typically, when a method returns an instance of an object, a temporary object is created and copied to the target object through a copy constructor. In the C + + standard, it is allowed to omit the copy constructor (even if it results in different program behavior), but there is a side effect that the compiler might take two objects as one. Visual C + + 8.0 (Visual C + + 2005) leverages the scalability of the C + + standard, adding some new features-named return value optimization (NRVO). Nrvo eliminates the copy constructors and destructors based on stack return values, and removes calls to redundant constructors and destructors, thereby improving program performance comprehensively. However, it should be noted that optimized and not optimized code may have different program behavior performance.
In some cases, NRVO will not be optimized (see the Limitations section of optimization), and here are some common scenarios:
• Different paths return different named objects
• Multiple return paths in EH state are introduced (even the same named objects are returned in all paths)
• Named returned objects referenced by an inline assembly statement
Nrvo Optimization Overview
Here's a simple example that shows how optimizations are implemented:
A MyMethod (B &var) { A RetVal; Retval.member = Var.value + Bar (VAR); return retVal; } |
A program that uses the above function might have a constructor like the following:
The value returned by MyMethod is created in memory space and points to vala by hidden arguments. The following are the functions that have hidden parameters and clearly specify the construction and destructor:
A MyMethod (a &_hiddenarg, B &var) { A RetVal; Retval.a::a (); Constructor for RetVal Retval.member = Var.value + Bar (VAR); _hiddenarg.a::a (RetVal); A's copy constructor Return Retval.a::~a (); destructor of retval } |
From the code above, it is clear that there are some areas that can be optimized. The basic idea is to eliminate the stack based temporary values (retVal) and use hidden parameters to eliminate the copy constructors and destructors based on stack values. The following are the Nrvo optimized code:
A MyMethod (a &_hiddenarg, B &var) { _hiddenarg.a::a (); _hiddenarg.member = Var.value + Bar (VAR); Return } |
Sample code
Sample1.cpp: Simpler Sample code
#include <stdio.h> Class RVO { Public RVO () {printf ("I AM in Constructor\n");} RVO (const rvo& C_rvo) {printf ("I am in Copy constructor\n");} ~rvo () {printf ("I AM in Destructor\n");} int Mem_var; };
RVO MyMethod (int i) { RVO RVO; Rvo.mem_var = i; return (RVO); }
int main () { RVO RVO; Rvo=mymethod (5); } |