• λ我爱Aspx >> C#.Net >> Visual C++ 2005中的命名返回值优化
  • Visual C++ 2005中的命名返回值优化

  • :aspxer  Դ:天极  :2007-4-30 22:27:38  ؼ:
  • 多年来,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);}
    Ҷƪл˵?
  • һƪ基于Windows通讯基础的事务性服务创建
    һƪVisual Basic .Net打造个性化菜单