传递shared_ptr的成本

Art*_*lov 57 c++ performance shared-ptr

我在整个应用程序中广泛使用std :: tr1 :: shared_ptr.这包括在函数参数中传递对象.考虑以下:

class Dataset {...}

void f( shared_ptr< Dataset const > pds ) {...}
void g( shared_ptr< Dataset const > pds ) {...}
...
Run Code Online (Sandbox Code Playgroud)

虽然通过shared_ptr传递数据集对象可以保证它在f和g中的存在,但是这些函数可能会被调用数百万次,这会导致很多shared_ptr对象被创建和销毁.这是最近一次运行的平坦gprof配置文件的片段:

Each sample counts as 0.01 seconds.
  %   cumulative   self              self     total
 time   seconds   seconds    calls   s/call   s/call  name
  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 ) {...}
Run Code Online (Sandbox Code Playgroud)

并替换电话

shared_ptr< Dataset > pds( new Dataset(...) );
f( pds );
Run Code Online (Sandbox Code Playgroud)

f( *pds );
Run Code Online (Sandbox Code Playgroud)

在我知道的地方,当程序流程在f()内时,对象不会被破坏.但是在我开始改变一堆函数签名/调用之前,我想知道传递shared_ptr的典型性能是什么.似乎不应该将shared_ptr用于经常调用的函数.

任何输入将不胜感激.谢谢阅读.

-Artem

更新:将少数函数更改为接受后const Dataset&,新配置文件如下所示:

Each sample counts as 0.01 seconds.
  %   cumulative   self              self     total
 time   seconds   seconds    calls   s/call   s/call  name
  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&)

由于析构函数调用的数量小于复制构造函数调用的数量,我有点困惑,但总体而言我对相关运行时间的减少感到非常满意.感谢大家的建议.

Sam*_*ell 57

始终传递你shared_ptrconst引用:

void f(const shared_ptr<Dataset const>& pds) {...} 
void g(const shared_ptr<Dataset const>& pds) {...} 
Run Code Online (Sandbox Code Playgroud)

编辑:关于他人提到的安全问题:

  • shared_ptr整个应用程序中大量使用时,按值传递将花费大量时间(我已经看到它达到50 +%).
  • 使用const T&而不是const shared_ptr<T const>&在参数不为null时使用.
  • 使用const shared_ptr<T const>&const T*性能问题更安全.

  • @Artem:如果你的方法要求`pds`为非null,那么肯定更喜欢`const Dataset&`.如果null是有效值,则只需传递`shared_ptr`. (3认同)
  • [Herb Sutter](http://en.wikipedia.org/wiki/Herb_Sutter)[推荐](http://channel9.msdn.com/Events/GoingNative/GoingNative-2012/C-11-VC-11-andand -Beyond)只是通过原始指针/参考(43分钟),除非你想做一些像存储它. (3认同)

Ale*_*x F 10

您只需将shared_ptr传递给函数/对象,以备将来使用.例如,某些类可以保留shared_ptr以在工作线程中使用.对于简单的同步调用,使用普通指针或引用就足够了.shared_ptr不应该完全使用普通指针替换.