为什么修剪下来的shared_ptr版本比boost :: shared_ptr慢?

时间:2017-03-11 09:56:06

标签: c++ performance boost shared-ptr reference-counting

我认为这已经非常简单而且做得不多(从其中一个堆栈溢出问题答案代码中取出),但运行100K次循环表明它比boost :: shared_ptr慢。困惑,缓慢来自何处?

template <class T>
class sp_shared_ptr
{
public:
        inline sp_shared_ptr() noexcept: p_(), count_() {}

        inline explicit sp_shared_ptr( T* p ) noexcept: p_( p ), count_( new int(1) )   {}

        inline sp_shared_ptr( const sp_shared_ptr& sp ) noexcept: p_( sp.p_ ), count_( sp.count_ )
        {
                if( count_ ) ++(*count_);
        }

        // EDIT: add in later based on comments
        sp_shared_ptr( sp_shared_ptr && r ) noexcept : p_( r.p_ ), count_()
        {
                int *tmp = r.count_;
                r.count_ = count_;
                count_ = tmp;
                r.p_ = 0;
        }

        sp_shared_ptr& operator=( const sp_shared_ptr& sp ) noexcept
        {
                if( this != &sp )
                {
                        clear();
                        p_ = sp.p_;
                        count_ = sp.count_;
                        if( count_ ) ++*count_;
                }
                return *this;
        }

        ~sp_shared_ptr() noexcept
        {
                clear();
        }

private:
        inline void clear() noexcept
        {
                if( count_ )
                {
                        --*count_;
                        if( *count_ == 0 ) {
                             delete p_;  p_=0;
                             delete count_;  count_=0;
                        }
                }
        }

        T* get() const { return count_ ? p_ : 0; }
        T* operator->() const { return get(); }
        T& operator*() const { return *get(); }

        T* p_;
        int* count_;
};

以下程序的输出是:

10229594
14577150
14030158

编辑:根据@ BoPersson的评论,在移动构造函数中编辑。现在,结果越来越近了:     10201099     14121221     14040181

我想知道为什么它更快,或者更快一点(没有原子计数器在我的测试中没有任何好处?)

致电计划:

#include <iostream>
#include <map>
#include <string>
#include <boost/shared_ptr.hpp>
#include <boost/smart_ptr.hpp>
#include <time.h>

#include "sp_shared_ptr.h"

struct A
{
  int a1;
  double a2;
  std::string a3;
};

long long duration( const timespec& t0, const timespec& t1 )
{
  return (t1.tv_sec*1000000000L + t1.tv_nsec) - (t0.tv_sec*1000000000L + t0.tv_nsec);
}

int main()
{
  typedef std::vector<std::unique_ptr<A>> UPVector;
  typedef std::vector<boost::shared_ptr<A>> SPVector;
  typedef std::vector<sp_shared_ptr<A>> MySPVector;

  UPVector v1;
  SPVector v2;
  MySPVector v3;

  const int n=100000;
  timespec t0, t1;
  clock_gettime( CLOCK_REALTIME, &t0 );

  clock_gettime( CLOCK_REALTIME, &t0 );
  {
    for( auto i=0; i < n; ++i )
      v1.push_back( std::unique_ptr<A>( new A { i, i/100.0, "aaaaaaaaaa" } ) );
  }
  clock_gettime( CLOCK_REALTIME, &t1 );
  std::cout << duration( t0, t1 ) << std::endl;

  clock_gettime( CLOCK_REALTIME, &t0 );
  {
    for( auto i=0; i < n; ++i )
      v3.push_back( sp_shared_ptr<A>( new A{ i, i/100.0, "aaaaaaaaaa" } ) );
  }
  clock_gettime( CLOCK_REALTIME, &t1 );
  std::cout << duration( t0, t1 ) << std::endl;

  clock_gettime( CLOCK_REALTIME, &t0 );
  {
    for( auto i=0; i < n; ++i )
      v2.push_back( boost::shared_ptr<A>( new A{ i, i/100.0, "aaaaaaaaaa" } ) );
  }
  clock_gettime( CLOCK_REALTIME, &t1 );
  std::cout << duration( t0, t1 ) << std::endl;

  return 0;
}

0 个答案:

没有答案