【发布时间】:2011-01-30 22:30:17
【问题描述】:
我在整个应用程序中广泛使用 std::tr1::shared_ptr。这包括将对象作为函数参数传入。考虑以下几点:
class Dataset {...}
void f( shared_ptr< Dataset const > pds ) {...}
void g( shared_ptr< Dataset const > pds ) {...}
...
虽然通过 shared_ptr 传递数据集对象可以保证其存在于 f 和 g 中,但函数可能会被调用数百万次,这会导致创建和销毁大量 shared_ptr 对象。这是最近运行的平面 gprof 配置文件的 sn-p:
每个样本计为 0.01 秒。 % 累计自我自我总计 时间 秒 秒 呼叫 s/呼叫 s/呼叫名称 9.74 295.39 35.12 2451177304 0.00 0.00 std::tr1::__shared_count::__shared_count(std::tr1::__shared_count const&) 8.03 324.34 28.95 2451252116 0.00 0.00 std::tr1::__shared_count::~__shared_count()因此,大约 17% 的运行时间用于使用 shared_ptr 对象进行引用计数。这正常吗?
我的应用程序的很大一部分是单线程的,我正在考虑将一些函数重写为
void f( const Dataset& ds ) {...}
并替换调用
shared_ptr< Dataset > pds( new Dataset(...) );
f( pds );
与
f( *pds );
在我确信当程序流在 f() 中时对象不会被破坏的地方。但在我跑去更改一堆函数签名/调用之前,我想知道通过 shared_ptr 传递的典型性能损失是什么。似乎 shared_ptr 不应该用于经常调用的函数。
任何意见将不胜感激。感谢阅读。
-阿尔泰姆
更新:在更改了一些函数以接受const Dataset& 后,新的配置文件如下所示:
我对析构函数调用的数量小于复制构造函数调用的数量感到有些困惑,但总的来说,我对相关运行时间的减少感到非常满意。感谢大家的建议。
【问题讨论】:
-
相关问题:在某些平台(例如旧版 ARM)上,引用计数需要锁定互斥体。这会使共享指针在实时上下文中不可用(通过引用除外)。
-
您是如何获得这些漂亮的基准数据的?
-
@Daniel:这只是来自
gprof的flat profile。
标签: c++ performance shared-ptr