优化构造函数调用的数量 [英] Optimizing the number of constructor calls

查看:93
本文介绍了优化构造函数调用的数量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在工作中,我们有一个类有一个昂贵的构造函数,所以我们希望它被调用尽可能少的次数。我们通过使用它,并试图让代码更RVO友好所以说。



但是我们发现了一个怪癖在g ++编译器,我们不明白发生了什么。



请考虑operator +

的两个实现

  const Imaginary Imaginary :: operator +(const Imaginary& rhs)const 
{
Imaginary tmp(* this);
tmp.append(rhs);
return tmp;
}

  const Imaginary Imaginary :: operator +(const Imaginary& rhs)const 
{
return Imaginary(* this).append(rhs);
}



我已将打印输出放在各种构造函数中,

  int main(int argc,char * argv [])
{
Imaginary x ,1);
Imaginary y(2,1);

Imaginary c = x + y;
return 0;
}

我打印出第一个operator +

  int / int ctor 
int / int ctor
复制ctor
pre>

当我们使用operator +的第二个变体时,我得到以下结果:

  int / int ctor 
int / int ctor
复制ctor
复制ctor

在这里我们看到g ++能够在一种情况下优化掉一个对复制构造函数的调用,而不是后者,令我感到惊讶的是,它设法使用更笨拙的



现在我可以理解它,如果它是另一种方式,但似乎它不是
现在我希望也许有一个你可以启发我对这个问题。



我应该补充一点,当我们添加--no-elide-constructors作为一个标志g ++
我得到以下打印输出

  int / int ctor 
int / int ctor
复制ctor
复制ctor
复制ctor

>

解决方案

如果编译器不能内联 append ,那么它不能确定返回值是目标对象。



你会有相同的行为:

  Imaginary tmp(* this); 
return tmp.append(rhs);

如果 append 的返回值不透明到编译器(在另一个编译单元中定义),它会阻止优化。


At work we have a class with an expensive constructor so we would like it to be called as few times as possible. We looked through the uses of it and tried to make the code more RVO friendly so to say.

However we found a quirk in the g++ compiler where we didn't understand what happened.

Please consider the two implementations of operator+

const Imaginary Imaginary::operator+(const Imaginary& rhs) const
{
    Imaginary tmp(*this);
    tmp.append(rhs);
    return tmp;
}

and

const Imaginary Imaginary::operator+(const Imaginary& rhs) const
{
    return Imaginary(*this).append(rhs);
}

I have put print-outs in the the various constructors and with the following little program

int main(int argc, char* argv[])
{
    Imaginary x(1, 1);
    Imaginary y(2, 1);

    Imaginary c = x + y;
    return 0;
}

I get this print out with the first implementation of operator+

int/int ctor
int/int ctor
Copy ctor

And I get the following when the second variant of operator+ is in use

int/int ctor
int/int ctor
Copy ctor
Copy ctor

Here we see that g++ is able to optimize away one call to the copy constructor in one case but not the latter and to my surprise, it managed to do it with the more clumsy implementation where I saved it to a temporary.

Now I could've understood it more if it was the other way around but appearantly it isn't and now I am hoping that maybe one you could enlighten me on this subject.

I should probably add that when we add --no-elide-constructors as a flag to g++ I get the following print out

int/int ctor
int/int ctor
Copy ctor
Copy ctor
Copy ctor

Regards, Mattias

解决方案

If the compiler cannot inline append, then it cannot determine that the return value is target object. Then it doesn't know that the temporary is being returned, and cannot construct it in place.

You would have the same behavior with:

Imaginary tmp(*this);
return tmp.append(rhs);

If the return value of append is opaque to the compiler (defined in another compilation unit), it prevents the optimization.

这篇关于优化构造函数调用的数量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆