++i i++ 编译器优化_C ++编译器实现的返回值优化技术

++i i++ 编译器优化

In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. Advances in compiler optimizations have all but eliminated this concern thanks to a clever set of optimizations implemented by most modern compilers.

在过去的日子里,必须避免从C ++函数中通过值返回某些东西,因为它总是涉及所创建对象的一个​​或什至两个副本,并且可能会昂贵地调用复制构造函数和析构函数。 由于大多数现代编译器实现了一系列聪明的优化,因此编译器优化方面的进展几乎消除了这种担忧。

The C++ standard allows the omission of the call to the copy constructor and, thus, allows the compiler to create a return value in the stack-frame of the calling function. This has the effect of allowing the compiler to treat both objects (in the caller and the callee) as the same entity, thus eliminating the need to take a copy.

C ++标准允许省略对复制构造函数的调用,从而允许编译器在调用函数的堆栈框架中创建返回值。 这样的效果是允许编译器将两个对象(在调用方和被调用方中)都视为同一实体,从而消除了制作副本的需要。

There are two versions of this optimization available, Named Return Value Optimization (NRVO) and Return Value Optimization (RVO). Although the end result is the same, the syntax and semantics of each is slightly different:

该优化有两个版本,分别是命名返回值优化(NRVO)和返回值优化(RVO)。 尽管最终结果是相同的,但是它们的语法和语义都略有不同:

RVO: Return Value Optimization is carried out when an object is constructed in-line within the return statement of a function, which would normally result in a temporary object being created on the stack, which is then copied into the calling functions stack-frame. When RVO is performed the object is created within the stack-frame of the calling function, thus avoiding the creation and destruction of an unnecessary temporary and the invocation of a copy constructor.

RVO:当在函数的return语句中内联构造对象时,将执行返回值优化,这通常会导致在堆栈上创建一个临时对象,然后将该临时对象复制到调用函数stack-frame中。 当执行RVO时,将在调用函数的堆栈框架内创建对象,从而避免不必要的临时对象的创建和销毁以及复制构造函数的调用。

// Example of RVO
Bar Foo()
{
	return Bar();
}

Without RVO

没有RVO

Items constructed: 2

建造物品:2

Items destructed: 1

被破坏的物品:1

Copies taken : 1

份数:1

With RVO

使用RVO

Items constructed: 1

建造物品:1

Items destructed: 0

被破坏的物品:0

Copies taken : 0

份数:0

NRVO: Named Return Value Optimization is carried out when an object is created with a name within the called function and is then returned by name, which would normally result in a temporary object being copied on the stack, which is then copied into the calling functions stack-frame. When NRVO is performed the named object is created within the stack-frame of the calling function, thus avoiding the creation and destruction of an unnecessary temporary and the invocation of, potentially, two copy constructors.

NRVO:在使用被调用函数中的名称创建对象之后,将通过名称返回该对象,从而进行命名返回值优化,这通常会导致将临时对象复制到堆栈中,然后将其复制到调用函数中堆栈框架。 执行NRVO时,将在调用函数的堆栈框架内创建命名对象,从而避免了不必要的临时临时对象的创建和销毁,并避免了可能使用的两个副本构造函数的调用。

// Example of NRVO
Bar Foo()
{
	Bar bar;
	return bar;
}

Without NRVO

没有NRVO

Items constructed: 3

建造物品:3

Items destructed: 2

被破坏的物品:2

Copies taken : 2

份数:2

With NRVO

与NRVO

Items constructed: 1

建造物品:1

Items destructed: 0

被破坏的物品:0

Copies taken : 0

份数:0

It should be obvious by now that when RVO or NRVO are used the copy-constructor on the returned object may not be called. For this reason it is very important that you do not write code that relies on the calling of a copy-constructor (such as instance counting, for example) since it may or may not be called depending upon the compiler, the optimization level and the way the function is written.

现在很明显,当使用RVO或NRVO时,可能不会调用返回对象上的复制构造函数。 因此,不要编写依赖于复制构造函数的调用(例如,实例计数)的代码,这一点非常重要,因为它可能会或可能不会被编译器,优化级别和编译器调用。函数的编写方式。

Each compiler implements support for RVN and NRVO to varying degrees so it is important to refer to your favourite compilers documentation to establish how well supported these two optimizations are.

每个编译器都在不同程度上实现了对RVN和NRVO的支持,因此务必参考您最喜欢的编译器文档以建立这两种优化的支持程度,这一点很重要。

It is not always possible for a compiler to carry out NRVO, code must be written to facilitate it. Again, this does vary from compiler to compiler but if there are multiple return paths you can be pretty sure NRVO will not take place.

编译器并非总是可以执行NRVO,必须编写代码以方便执行。 同样,每个编译器的确有所不同,但是如果有多个返回路径,则可以确定NRVO不会发生。

// Example of N/RVO 
#include <iostream>
 
struct MyClass
{
	MyClass()
	{
		std::cout << "MyClass::c_tor()" << std::endl;
	}
	
	MyClass(MyClass const &)
	{
		std::cout << "MyClass::cc_tor()" << std::endl;
	}
	
	~MyClass()
	{
		std::cout << "MyClass::d_tor()" << std::endl;
	}
}; 
MyClass NRVO()
{
	std::cout << "Named Return value Optimization" << std::endl;
	
	MyClass myClass;
	return myClass;
};
 
MyClass RVO()
{
	std::cout << "Return value Optimization" << std::endl;
	
	return MyClass();
}; 
MyClass NoNRVO()
{
	std::cout << "** NO *** Named Return value Optimization -- this is unlikely to optimize" << std::endl;
	
	if(0)
	{
		MyClass myClass;
		return myClass;
	}
	else
	{
		MyClass myClass;
		return myClass;
	}
}; 
MyClass NoRVO()
{
	std::cout << "** NO *** Return value Optimization ??? -- this should still optimize" << std::endl;
	
	if(0)
	{
		return MyClass();
	}
	else
	{
		return MyClass();
	}
}; 
int main(void)
{
	std::cout << ">>> START >>>" << std::endl;
	
	MyClass myClass1 = NRVO();
	MyClass myClass2 = RVO();
	
	MyClass myClass3 = NoNRVO();
	MyClass myClass4 = NoRVO(); 
	std::cout << "<<< END <<<" << std::endl;
}

翻译自: https://www.experts-exchange.com/articles/771/Return-Value-Optimization-techniques-implemented-by-C-compilers.html

++i i++ 编译器优化

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值