我在整个应用程序中广泛使用 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 配置文件的片段:
每个样本计为 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 不应该用于经常调用的函数。
任何输入将不胜感激。谢谢阅读。
-Artem
更新:将一些函数更改为 acceptconst Dataset&
后,新配置文件如下所示:
每个样本计为 0.01 秒。 % 累计自我自我总计 时间 秒 秒 呼叫 s/呼叫 s/呼叫名称 0.15 241.62 0.37 24981902 0.00 0.00 std::tr1::__shared_count::~__shared_count() 0.12 241.91 0.30 28342376 0.00 0.00 std::tr1::__shared_count::__shared_count(std::tr1::__shared_count const&)
我对析构函数调用的数量小于复制构造函数调用的数量感到有点困惑,但总的来说,我对相关运行时间的减少感到非常满意。感谢大家的建议。