【问题标题】:Copy method optimization in compilers编译器中的复制方法优化
【发布时间】:2010-04-03 15:10:04
【问题描述】:

我有以下代码:

void Stack::operator =(Stack &rhs)
{
    //do the actual copying
}

Stack::Stack(Stack &rhs) //copy-constructor
{
    top=NULL; //initialize this as an empty stack (which it is)
    *this=rhs; //invoke assignment operator
}

Stack& Stack::CopyStack()
{
    return *this; //this statement will invoke copy contructor
}

它是这样使用的:

unsigned Stack::count()
{
    unsigned c=0;
    Stack copy=CopyStack();
    while (!copy.empty())
    {
        copy.pop();
        c++;
    }
    return c;
}

从 CopyStack 的声明中删除引用符号(返回副本而不是引用)在 Visual Studio 2008 中没有区别(关于调用复制的次数)。我猜它会被优化掉——通常它应该首先为返回值制作一个副本,然后再次调用赋值运算符将它分配给变量 sc。

您对不同编译器中的这种优化有何经验?

问候, 哲南

【问题讨论】:

  • 旁白:您的复制构造函数和operator = 应该使用const 引用。
  • 这实际上是一个非常简单的作业——一个只有 119 行实现的类。每个方法最多被调用几次,并且永远不会被扩展。问这个问题的原因是它在 C++ 教科书中得到了广泛的关注。在这个程序中,性能不是任何问题——复制堆栈只使用 push 和 pop 方法实现——这使得它非常低效。并且计数本来可以作为私有变量保存,等等。
  • 您的问题实际上是:“实际上,编译器是否消除了使用复制初始化的定义中的临时变量?”,因为代码中的注释似乎显示了误解关于作为返回值的引用。
  • 好吧,当我写那条评论时,我希望临时被复制。后来我发现编译后的代码是按照我想要的方式优化的。

标签: c++ copy containers compiler-optimization


【解决方案1】:

此语句是从CopyStack() 的返回值复制初始化名为copyStack。没有任务。

Stack copy=CopyStack();

在此函数中,注释不正确。没有调用复制构造函数,因为返回值是一个引用。

Stack& Stack::CopyStack()
{
    return *this; //this statement will invoke copy contructor
}

这意味着原始初始化实际上是从*this 变量复制构造。

如果返回值是值,那么复制初始化将来自一个临时的,但编译器可以有效地消除它。

我看不出CopyStack 函数的意义所在。只执行直接初始化会更惯用:

Stack copy(*this);

【讨论】:

  • 感谢您花时间发布答案。 CopyStack 方法的重点是符号方便,或者更好的答案是我首先编写了 CopyStack 方法,只是在最初的想法不起作用时才将其替换为 3 种方法的组合。控制权交给了复制构造函数,虽然后来——而且这个评论更多的是给我自己的。我更希望有人对 GCC 或其他编译器有经验(关于此类事情的优化)并可以与我们分享。
【解决方案2】:

如果我理解正确,您可以为堆栈对象制作原型并返回原型,这可能会带来一些性能,但您必须注意内存资源的对象所有权。

如果您愿意,可以使用原型工厂设计模式。

【讨论】:

  • 感谢您抽出宝贵的时间,但您似乎也没有抓住重点,就像 Thomas(见对第一篇文章的评论)和 Charles Bailey 一样。
【解决方案3】:

我猜您正在寻找的是 RVO(返回值优化)和 NRVO(命名返回值优化)。编译器优化是一个庞大的主题,如果我要开始输入描述,那将花费太长时间!看看这个blog post...它很好地解释了它。

【讨论】:

  • GCC,顺便说一句,像大多数其他编译器一样应用这两种算法。此外,您可能有兴趣查看 C++0x 的“移动语义”。移动语义可以消除不必要的对象复制,只需利用这样一个事实,即复制一个没有被其他任何东西引用并且很快就会被销毁的临时对象是没有意义的。
  • 其实我很惊讶编译器对我的代码进行了很好的优化,而对 C++ 的所有批评都存在。
  • 批评??好吧,对我来说,C++ 一直是一种非常强大的语言(我讨厌托管代码!),但是,嘿……每个故事都有两个方面,不是吗?
  • 我已经看过 C++0x 几次了 - 我认为它很棒,现在我只是等待最终规范出现并被实施。
  • C++ 也是我的母语编程语言。我很高兴阅读其中的一些内容:yosefk.com/c++fqa
猜你喜欢
  • 2011-03-24
  • 1970-01-01
  • 1970-01-01
  • 2016-05-24
  • 1970-01-01
  • 2012-03-29
  • 2016-06-30
  • 2011-11-07
  • 2017-06-09
相关资源
最近更新 更多