通过shared_ptr的成本 [英] The cost of passing by shared_ptr
问题描述
我在我的应用程序中广泛使用std :: tr1 :: shared_ptr。这包括作为函数参数传递对象。请考虑以下内容:
I use std::tr1::shared_ptr extensively throughout my application. This includes passing objects in as function arguments. Consider the following:
class Dataset {...}
void f( shared_ptr< Dataset const > pds ) {...}
void g( shared_ptr< Dataset const > pds ) {...}
...
当通过shared_ptr传递数据集对象时,保证它在f和g中的存在,函数可能被调用百万次,这会导致创建很多shared_ptr对象,销毁。以下是最近一次运行的gprof配置文件的片段:
While passing a dataset object around via shared_ptr guarantees its existence inside f and g, the functions may be called millions of times, which causes a lot of shared_ptr objects being created and destroyed. Here's a snippet of the flat gprof profile from a recent run:
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对象的引用计数。这是正常的吗?
So, ~17% of the runtime was spent on reference counting with shared_ptr objects. Is this normal?
我的应用程序的大部分是单线程的,我正在考虑重写一些函数
A large portion of my application is single-threaded and I was thinking about re-writing some of the functions as
void f( const Dataset& ds ) {...}
并替换调用
shared_ptr< Dataset > pds( new Dataset(...) );
f( pds );
f( *pds );
在我知道的地方,确保对象不会被销毁, F()。但在我跑掉改变一堆函数签名/调用之前,我想知道shared_ptr传递的典型性能。看起来像shared_ptr不应该用于被频繁调用的函数。
in places where I know for sure the object will not get destroyed while the flow of the program is inside f(). But before I run off to change a bunch of function signatures / calls, I wanted to know what the typical performance hit of passing by shared_ptr was. Seems like shared_ptr should not be used for functions that get called very often.
任何输入都将不胜感激。非常感谢阅读。
Any input would be appreciated. Thanks for reading.
-Artem
更新:函数接受 const Dataset&
,新配置文件如下所示:
Update: After changing a handful of functions to accept const Dataset&
, the new profile looks like this:
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&)
有点困惑的析构函数调用的数量小于复制构造函数调用的数量,但总体来说,我非常高兴关联运行时间的减少。
I'm a little puzzled by the number of destructor calls being smaller than the number of copy constructor calls, but overall I'm very pleased with the decrease in the associated run-time. Thanks to all for their advice.
推荐答案
始终通过您的 shared_ptr
const 参考:
void f(const shared_ptr<Dataset const>& pds) {...}
void g(const shared_ptr<Dataset const>& pds) {...}
修改: 关于他人提及的安全问题:
Regarding the safety issues mentioned by others:
- 使用<$当参数不应为空时,
c> c <$ c> const T& 而不是 const shared_ptr
。 b $ b& - 使用
const shared_ptr< T const>&
比const T *
一个问题。
- 使用
< shared_ptr 在整个应用程序中,通过值将占用大量的时间(我看到它走50 +%)。
- When using
shared_ptr
heavily throughout an application, passing by value will take up a tremendous amount of time (I've seen it go 50+%). - Use
const T&
instead ofconst shared_ptr<T const>&
when the argument shall not be null. - Using
const shared_ptr<T const>&
is safer thanconst T*
when performance is an issue.
这篇关于通过shared_ptr的成本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!