代码之家  ›  专栏  ›  技术社区  ›  Flamefire

共享指针的复制和交换效率

  •  1
  • Flamefire  · 技术社区  · 6 年前

    Why shared pointer assignment does 'swap'? .

    问题是关于使用的复制和交换习惯用法 e.g. in boost

    我知道Copy&Swap的好处是重用现有代码,从而避免重复和错误。但有两种情况(实际上一种情况可以简化为另一种情况)不是最优的:

    1. 智能指针实例是相同的

    为了 shared_ptr ref计数器是 为了 intrusive_ptr (仅限增强型)可能是。所以有一个 一份副本。

    如果任务的执行方式如下所示,则可以避免这种情况:

    smart_ptr& operator=(const smart_ptr& other){
      if(this->ptr_ == other.ptr_) return *this;
      smart_ptr(other).swap(*this); // I assume I can simply do this here, right?
      return *this;
    }
    smart_ptr& operator=(smart_ptr&& other){
      smart_ptr(std::move(other)).swap(*this);
      return *this;
    }
    

    这难道不是最快、最安全的实现吗?还是有什么问题我没有看到?

    澄清第二点。请考虑以下代码:

    smart_ptr a(new foo);
    auto b = a;
    ...
    // Eventually:
    a = b;
    

    这是 自我分配为 &a != &b . 复制和交换

    1 回复  |  直到 6 年前
        1
  •  0
  •   wdudzik    6 年前

    自我分配并不是一个常见的情况,因此每次测试都要花费更多的时间来交换它。复制指针基本上是最快的复制。

    复制共享的ptr的实际成本是原子引用增量(这可能涉及在下面使用互斥)。

    如果您真的想测试这两种方法的性能,我建议您 google benchmark 库并编写一组测试用例(用于自分配和所有其他用例)并对其进行度量。请记住,现在的优化器可以用您的代码来优化它。如果不测量它,很难判断它是否更快,但我想如果没有它的版本是相当昂贵的更好:)

    编辑:

    如果不想增加引用计数(复制共享的ptr时这是很昂贵的部分),可以始终使用move构造函数:

    smart_ptr a(new foo);
    auto b = a;
    ...
    // Eventually:
    a = std::move(b);
    
    推荐文章