是否更好地移动shared_ptr?

时间:2016-07-16 15:28:15

标签: c++ c++11 std shared-ptr

我有一个方法

structA
{
     shared_ptr<B> m_b;

     // 2 options to set m_b

     void setB1(shared_ptr<B> b)
     {
         m_b = move(b);
     }

     void setB2(shared_ptr<B> const&b)
     {
         m_b = b;
     }
};

哪一个性能更好?如果我将setB1称为setB1(b)而不是setB1(move(b)),则他们都会复制。当b可以无效且b只能被复制时,我更关心它的性能。

我在VC2015上的测试答案:

setB1setB2

  • 30%左右为左值b
  • 乘以8%的rvalue b

2 个答案:

答案 0 :(得分:0)

这里的表现差异很小。

其中一个会在参数中创建一个副本,然后移出它。

另一个引用参数中的外部副本,并复制出来。

如果你使用共享ptr创建函数(如make_shared)调用第一个,你将获得1次移动,0次复制和1次琐碎破坏。对于第二个,你得到0个动作,1个副本和1个非平凡的破坏。

如果你通过值调用第一个只是传递一些随机共享ptr,你得到1个副本,1个移动和1个普通的破坏。在第二个中,你得到1个副本和0个移动。

复制共享ptr是原子增量。琐碎的毁灭是一个分支。非平凡是分支和原子减量。移动共享ptr只是设置一些指针。

答案 1 :(得分:0)

答案是肯定的,通常 setB1 更好。

  • 复制共享指针会导致对引用计数的昂贵(缓慢)原子递增/递减操作。

  • 移动共享指针几乎是免费的,基本上只是非原子地复制指针(可能是单个汇编指令)。

在您的示例中,setB1 为用户提供移动或复制 shared_ptr 的选择,从而在用户可以移动时实现最佳性能,而 setB2 强制复制。

在此处查看性能差异的详细说明: Why would I std::move an std::shared_ptr?