c++ shared_ptr实现 - 我们应该通过引用还是通过值来传递shared_ptr?




4 Answers

Scott,Andrei和Herb在C ++及2011年以后的 Ask Us Anything会议期间讨论并回答了这个问题。 从4分34秒观看shared_ptr性能和正确性

很快,除非目标是共享对象的所有权(例如,在多个线程之间),否则没有理由通过价值传递

除非您可以按照Scott Meyers在上面链接的谈话视频中所解释的那样移动 - 优化它,但这与您可以使用的C ++的实际版本有关。

2012年GoingNative会议的互动小组讨论中发生了这次讨论的主要更新:问我们任何问题! 值得关注,尤其是22:50

shared_ptr参数传递 shared_ptr循环引用

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

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

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

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

你能否给出你选择的理由,或者如果是这种情况,为什么你认为这没有关系。




我个人会使用一个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版本构建

const shared_ptr&     - 10ms  
shared_ptr            - 281ms 

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




不知道shared_copy复制操作的原子增量和减量的时间成本,我遭受了更高的CPU使用率问题。 我从未想过原子的增量和减量可能会花费很多成本。

根据我的测试结果,int32原子增量和减量比非原子增量和减量要多2或40倍。 我在Windows 8.1上使用3GHz Core i7。 前者的结果在没有争用发生时出现,后者在争用发生的可能性很高时出现。 我记住原子操作最后是基于硬件的锁。 锁是锁。 争用发生时对性能不利。

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




Related