我认为这已经非常简单而且做得不多(从其中一个堆栈溢出问题答案代码中取出),但运行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;
}