多年来,microsoft visual c++编译器一直在努力寻求更新的技术与优化方式,以求最大可能地提高程序的性能。此文描述了visual c++编译器在不同情况下,是怎样消除多余的复制构造函数和析构函数的。
通常来说,当方法返回对象的一个实例时,会创建一个临时对象,并通过复制构造函数复制到目标对象中。在c++标准中,允许省略复制构造函数(哪怕会导致不同的程序行为),但这有一个副作用,就是编译器可能会把两个对象当成一个。visual c++ 8.0(visual c++ 2005)充分利用了c++标准的可伸缩性,加入了一些新的特性——命名返回值优化(nrvo)。nrvo消除了基于堆栈返回值的复制构造函数和析构函数,并去除了对多余复制构造函数和析构函数的调用,从而全面地提高了程序的性能。但要注意到,优化和未优化的代码,可能会有不同的程序行为表现。
而在某些情况下,nrvo不会进行优化(参见优化的局限性一节),以下是一些常见的情况:
·不同的路径返回不同的命名对象
·引入eh状态的多重返回路径(甚至所有的路径中返回相同的命名对象)
·由内联汇编语句引用的命名返回对象
nrvo优化概述
以下是一个简单的示例,演示了优化是怎样被实现的:a mymethod (b &var)
{
a retval;
retval.member = var.value + bar(var);
return retval;
}
使用上述函数的程序可能会有一个像如下所示的构造函数:vala = mymethod(valb);
由mymethod返回的值会创建在内存空间中,并通过隐藏的参数指向vala。以下是函数中带有隐藏参数,并清晰地写明构造和析构函数时样子:a mymethod (a &_hiddenarg, b &var)
{
a retval;
retval.a::a(); // retval的构造函数
retval.member = var.value + bar(var);
_hiddenarg.a::a(retval); // a的复制构造函数
return;
retval.a::~a(); // retval的析构函数
}
从以上代码中,很明显可看出有一些可以优化的地方。最基本的想法是消除基于堆栈的临时值(retval),并使用隐藏参数,从而消除那些基于堆栈值的复制构造函数和析构函数。以下是nrvo优化过的代码:a mymethod(a &_hiddenarg, b &var)
{
_hiddenarg.a::a();
_hiddenarg.member = var.value + bar(var);
return
}
示例代码
sample1.cpp:比较简单的示例代码#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);
}
打开或关闭nrvo编译sample1.cpp,将会产生不同的程序行为。
不带nrvo编译(cl /od sample1.cpp),下面是输出内容: i am in constructor
i am in constructor
i am in copy constructor
i am in destructor
i am in destructor
i am in destructor
用nrvo选项编译(cl /o2 sample1.cpp),以下是输出内容: i am in constructor
i am in constructor
i am in destructor
i am in destructor
sample2.cpp:较复杂一点的代码#include <stdio.h>
class a {
public:
a() {printf ("a: i am in constructor\n");i = 1;}
~a() { printf ("a: i am in destructor\n"); i = 0;}
a(const a& a) {printf ("a: i am in copy constructor\n"); i = a.i;}
int i, x, w;
};
class b {
public:
a a;
b() { printf ("b: i am in constructor\n");}
~b() { printf ("b: i am in destructor\n");}
b(const b& b) { printf ("b: i am in copy constructor\n");}
};
a mymethod()
{
b* b = new b();
a a = b->a;
delete b;
return (a);
}
int main()
{
a a;
a = mymethod();
}
不带nrvo(cl /od sample2.cpp)的输出如下:a: i am in constructor
a: i am in constructor
b: i am in constructor
a: i am in copy constructor
b: i am in destructor
a: i am in destructor
a: i am in copy constructor
a: i am in destructor
a: i am in destructor
a: i am in destructor
当打开nrvo优化时,输出如下:a: i am in constructor
a: i am in constructor
b: i am in constructor
a: i am in copy constructor
b: i am in destructor
a: i am in destructor
a: i am in destructor
a: i am in destructor
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器