`
qepwqnp
  • 浏览: 105959 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

boost::shared_ptr的性能

阅读更多

原文出版:http://www.darkbull.net/

在最近的项目中,使用了大量的boost::shared_ptr。在游戏服务器中,有时候同一数据块要发送给不同的连接(例如A玩家的一个行走消息包要发给所有附近的玩家),如果为每个连接都拷贝一份数据,显的代价比较大且难以维护,想想发送完数据之后还要释放这些数据块,极易出错,而且性能也不佳。使用智能指针,只需要一份数据块的拷贝,并且不需要去管理内存的释放。但这几天,我又在想,boost::shared_ptr号称是线程安全的,那么在低层维护对象的引用计数时,必定有加琐/解琐。如果频繁的对智能指针进行复制,性能开销也不能忽略。我现在对boost的线程库使用还不是很熟练,网上查了一下,shared_ptr好像是通过Boost.Thread的mutex对象来保护引用计数,如果真是这样,那么我推断:在windows上使用shared_ptr,性能肯定没有直接使用windows api来进行同步的智能指针性能高。基于这样的猜测,我自己写了一些简单的智能指针,通过windows api Interlocked系列函数来维护智能指针引用计数。大概代码如下:

#ifndef AUTOPTR_H_INCLUDED
#define AUTOPTR_H_INCLUDED

#include <windows.h>

template<typename T>
class AutoPtr
{
public:
    AutoPtr(void)
        : _ptr(0), _refCount(0)
    { }

    explicit AutoPtr(T *ptr)
        : _ptr(ptr)
    {
        _refCount = new long(1);
    }

    AutoPtr(const AutoPtr &rhs)
        : _ptr(rhs._ptr), _refCount(rhs._refCount)
    {
        if (_ptr && _refCount)
            ::InterlockedIncrement(_refCount);  // 引用计数加1
    }

    ~AutoPtr(void)
    {
        if (!_ptr)
            return;

        long refCount = ::InterlockedExchangeAdd(_refCount, -1);
        if (refCount == 1)
        {
            delete _refCount;
            delete _ptr;
        }
    }

    T &operator*(void)
    {
        return *_ptr;
    }

    const T&operator*(void) const
    {
        return *_ptr;
    }

    T *operator->(void)
    {
        return _ptr;
    }

    const T*operator->(void) const
    {
        return _ptr;
    }

    const AutoPtr &operator=(const AutoPtr &rhs);

//    T *get(void)
//    {
//        return _ptr;
//    }
//
//    const T *get(void) const
//    {
//        return _ptr;
//    }
//
//    T *release(void)
//    {
//
//    }
//
//    void reset(T *ptr)
//    {
//
//    }

private:
    T *_ptr;
    long *_refCount;
};

template<typename T>
const AutoPtr<T> &AutoPtr<T>::operator=(const AutoPtr &rhs)
{
    if (_ptr)
    {
        long refCount = ::InterlockedExchangeAdd(_refCount, -1);
        if (refCount == 1)
        {
            delete _refCount;
            delete _ptr;
        }
    }

    _ptr = rhs._ptr;
    _refCount = rhs._refCount;
    if (_refCount)
        ::InterlockedIncrement(_refCount);

    return *this;
}

#endif // AUTOPTR_H_INCLUDED

并写了一个简单的测试程序,用来对比自己写的AutoPtr,boost::shared_ptr,std::tr1::shared_ptr。测试代码如下:

int main(int argc, char *argv[])
{
	AutoPtr<int> intPtr1(new int(0));
    time_t beg1 = clock();
    for (int i = 0; i < 10000000; ++i)
    {
        AutoPtr<int> tmp = intPtr1;
        ++(*tmp);
    }
    time_t end1 = clock();
	std::cout << "AutoPtr cost: " << end1 - beg1 << ", Result: " << *intPtr1 << std::endl;

	boost::shared_ptr<int> intPtr2(new int(0));
	time_t beg2 = clock();
	for (int i = 0; i < 10000000; ++i)
	{
		 boost::shared_ptr<int> tmp = intPtr2;
		 ++(*tmp);
	}
	time_t end2 = clock();
	std::cout << "boost::shared_ptr cost:" << end2 - beg2 << ", Result: " << *intPtr2 << std::endl;

	std::tr1::shared_ptr<int> intPtr3(new int(0));
	time_t beg3 = clock();
	for (int i = 0; i < 10000000; ++i)
	{
		std::tr1::shared_ptr<int> tmp = intPtr3;
		 ++(*tmp);
	}
	time_t end3 = clock();
	std::cout << "std::tr1::shared_ptr cost:" << end3 - beg3 << ", Result: " << *intPtr3 << std::endl;

	return 0;
}

结果出乎我的意料:

在VC9下的结果为:

VC9 Release结果

在gcc4.4.2下的结果:

gcc4.4.2 Release结果

结果表明,boost:;shared_ptr的性能并没有我想像是的那么差,在vc9下,三种智能指针的性能在同一水平上;而在gcc4.4.2下,boost::shared_ptr与AutoPtr性能相近,但与tr1版本的shared_ptr相差一个数量级。

分享到:
评论

相关推荐

    shared_from_this() in Constructor:直接替换std :: shared_ptr + std :: enable_shared_from_this-开源

    显然,许多人不喜欢标准std :: enable_... boost库也可以这样做,但是它不允许在析构函数中创建shared_ptrs,并且它不提供release()方法来获取所包含指针的所有权。 但是,不利的一面是,它还没有成为线程安全的。

    shared_ptr

    shared_ptr boost audio video AVDataPool

    shared_ptr线程安全性全面分析

    shared_ptr的线程安全性boost官方文档对shared_ptr线程安全性的正式表述是:shared_ptr对象提供与内置类型相同级别的线程安全性。【shared_ptrobjects offer the same level of thread safety as built-in types.】...

    浅析Boost智能指针:scoped_ptr shared_ptr weak_ptr

    scoped_ptrboost::scoped_ptr和std::auto_ptr非常类似,是一个简单的智能指针,它能够保证在离开作用域后对象被自动释放。下列代码演示了该指针的基本应用: 代码如下:#include &lt;string&gt;#include &lt;iostream&gt;#...

    C++11 智能指针之shared_ptr代码详解

    C++中的智能指针首先出现在“准”标准库boost中。 随着使用的人越来越多,为了让开发人员更方便、更安全的使用动态内存,C++11也引入了智能指针来管理动态对象。 在新标准中,主要提供了shared_ptr、unique_ptr、...

    C++智能指针详解.pdf

    #include &lt;boost/shared_ptr.hpp&gt; class CBase: public boost::enable_shared_from_this&lt;CBase&gt; { public: virtual void f(){}//必须有个虚函数才能向上向下转换。 } typedef boost::shared_ptr&lt;CBase&gt; CBasePtr; ...

    C++开发:为什么多线程读写shared_ptr要加锁的详细介绍

    根据文档(http://www.boost.org/doc/libs/release/libs/smart_ptr/shared_ptr.htm#ThreadSafety), shared_ptr 的线程安全级别和内建类型、标准库容器、std::string 一样,即: • 一个 shared_ptr 对象实体可被多...

    详解C++中shared_ptr的使用教程

    shared_ptr是一种智能指针(smart pointer)。shared_ptr的作用有如同指针,但会记录有多少个shared_ptrs共同指向一个对象。 这便是所谓的引用计数(reference counting)。一旦最后一个这样的指针被销毁,也就是...

    c++ shared_ptr智能指针使用注意事项

    shared_ptr在boost中地位相当重要,其行为接近原始指针,但又比指针更加安全,甚至还能提供基本的线程安全保证。它基本上解决了在使用c++开发过程中不可避免的使用指针而遇到的许多问题,常见的毫无疑问是内存泄漏和...

    C++智能指针(1).pdf

    C++ 中有四种智能指针:auto_pt、unique_ptr、shared_ptr、weak_ptr 其中后三个是 C++11 ⽀持,第⼀个已经被 C++11 弃⽤且被 unique_prt 代替,不推荐使⽤。下⽂将对其逐个说明。 std::auto_ptr 在这个年代讨论 std...

    st_asio_wrapper一组包装boost.asio的c/s框架(2.3版)

    这样带来一个问题,原来所有的接口中的boost::shared_ptr&lt;std::string&gt;数据类型,全部换成了std::string引用,升级到2.3的朋友要注意修改之前重写虚函数的签名,如果不改,则重写肯定不生效,变成了新增加虚函数了...

    st_asio_wrapper——一组包装boost.asio的c/s框架(2.3版)

    这样带来一个问题,原来所有的接口中的boost::shared_ptr&lt;std::string&gt;数据类型,全部换成了std::string引用,升级到2.3的朋友要注意修改之前重写虚函数的签名,如果不改,则重写肯定不生效,变成了新增加虚函数了...

    C++智能指针用法详解

    一、简介  由于 C++ 语言没有自动...包括:std::auto_ptr、boost::scoped_ptr、boost::shared_ptr、boost::scoped_array、boost::shared_array、boost::weak_ptr、boost:: intrusive_ptr。你可能会想,如此多的智能指

    C++智能指针实例详解

    本文通过实例详细阐述了C++关于智能指针的概念及用法,有助于读者加深对智能指针的理解。...包括:std::auto_ptr、boost::scoped_ptr、boost::shared_ptr、boost::scoped_array、boost::shared_array、boost::

    OpenSceneGraph2.7.3源代码 OSG2.7.3源代码

    * 新的ref_ptr函数,提供了更大的灵活性,以及osg::Referenced与boost::shared_ptr指针的互用性; * 改进了ImageSequence类的实现; * 新的osg3cpp实用程序,用于将GLSL着色器文件转换为可以直接编译到程序中的....

    microhttpd的c++封装接口

    microhttpd 的c++封装接口, head only, 包含... http.GET("/chen/test3", [](boost::shared_ptr&lt;Response&gt; res, boost::shared_ptr&lt;Request&gt; req){ res-&gt;write("handle test3 url request"); }); http.run();

    C++ boost::asio编程-域名解析详细介绍

    C++ boost::asio编程-域名解析 在网络通信中通常我们并不直接...#include boost/shared_ptr.hpp #include boost/thread.hpp #include &lt;boost&gt;//使用字符串转换功能 using namespace std; using namespace boost::asi

Global site tag (gtag.js) - Google Analytics