通过引用或值的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不够大,其构造函数\析构函数也没有做足够的工作,从副本有足够的开销,以关心引用传递与传递复制性能。