通过引用或值的shared_ptr?

当一个函数需要一个shared_ptr (来自boost或C ++ 11 STL)时,你是否传递它

  • 通过const引用: void foo(const shared_ptr<T>& p)

  • 或值: void foo(shared_ptr<T> p)

我宁愿第一种方法,因为我怀疑它会更快。 但是,这真的值得吗?还是还有其他问题?

请给出你select的理由或者如果是这样的话,为什么你认为这没有关系。

这个问题已经由Scott,Andrei和Herb在C ++及2011年以后的 Ask Us Anything会议上讨论和解答。 从4分34秒注意shared_ptr性能和正确性 。

不久之后, 没有理由超越价值 ,除非multithreading正在进行,但这需要单独考虑。

除非您可以像Scott Meyers在上面链接的videovideo中解释的那样对其进行移动优化,但是这与您可以使用的C ++的实际版本有关。

在2012年GoingNative会议的互动式小组讨论中,发生了一次重大的更新:询问我们任何事情! 值得一看,特别是从22:50开始 。

我个人会使用一个const引用。 为了调用函数,不需要增加引用计数。

这是香草萨特的采取

指南:除非您想使用或操纵智能指针本身,例如共享或传输所有权,否则不要将智能指针作为函数parameter passing。

指导原则:expression一个函数将使用by-value shared_ptr参数来存储和共享堆对象的所有权。

指南:只使用非const的shared_ptr&参数来修改shared_ptr。 只有当你不确定你是否会获得副本和共享所有权时,才使用const shared_ptr&作为参数; 否则使用小部件*代替(或者如果不能为空,一个小部件&)。

通过const引用传递,速度更快。 如果你需要存储它,说在一些容器,参考。 计数将自动地通过复制操作而神奇地增加。

我运行下面的代码,一次用foo通过const&获取shared_ptr ,然后再通过foo通过值来获取shared_ptr

 void foo(const std::shared_ptr<int>& p) { static int x = 0; *p = ++x; } int main() { auto p = std::make_shared<int>(); auto start = clock(); for (int i = 0; i < 10000000; ++i) { foo(p); } std::cout << "Took " << clock() - start << " ms" << std::endl; } 

在我的英特尔酷睿2四核(2.4GHz)处理器上使用VS2015,x86版本构build

 const shared_ptr& - 10ms shared_ptr - 281ms 

按价值复制的版本慢了一个数量级。
如果您正在从当前线程同步调用一个函数,则更喜欢const&版本。

因为C ++ 11,你应该把它比const更频繁地使用它。

如果你正在使用std :: shared_ptr(而不是基础typesT),那么你正在这样做,因为你想用它做一些事情。

如果你想某个地方复制它 ,通过复制和std ::内部移动,而不是通过const&,然后复制它是更有意义的。 这是因为你在调用你的函数的时候允许调用者selectstd :: move shared_ptr,从而为你自己节省一些增量和减量操作。 或不。 也就是说,函数的调用者可以在调用函数之后决定是否需要std :: shared_ptr,并根据是否移动来决定。 如果你通过const&来传递,那么这是不可能实现的,因此最好是通过值来实现。

当然,如果调用者都需要他的shared_ptr更长时间(因此不能std :: move),并且你不想在函数中创build一个简单的副本(比如说你想要一个弱指针,或者你只是有时想复制它,取决于一些条件),那么const&可能仍然是可取的。

例如,你应该这样做

 void enqueue(std::shared<T> t) m_internal_queue.enqueue(std::move(t)); 

过度

 void enqueue(std::shared<T> const& t) m_internal_queue.enqueue(t); 

因为在这种情况下,你总是在内部创build一个副本

不知道在primefaces增量和减量的情况下shared_copy复制操作的时间成本,我遭受了更高的CPU使用率问题。 我从来没有想过primefaces的增量和减量可能会花费这么多的成本。

在我的testing结果之后,int32的primefaces增量和减量比非primefaces增量和减量要多2或40倍。 我使用Windows 8.1在3GHz Core i7上运行。 前者的结果是在没有争用的情况下出现,后者是争用发生的可能性很高。 我记住,primefaces操作最后是基于硬件的锁。 锁是锁。 争用发生时对性能不好。

遇到这种情况,我总是使用byref(const shared_ptr&)而不是byval(shared_ptr)。

shared_ptr不够大,其构造函数\析构函数也没有做足够的工作,从副本有足够的开销,以关心引用传递与传递复制性能。