在我的测试中,make_shared(boost 或 stl)似乎比 shared_ptr+new 稍慢

Posted

技术标签:

【中文标题】在我的测试中,make_shared(boost 或 stl)似乎比 shared_ptr+new 稍慢【英文标题】:make_shared (boost or stl) seems slightly slower than shared_ptr+new in my tests 【发布时间】:2016-07-12 15:33:31 【问题描述】:

我对我对 make_shared 性能(boost 或 stl)的理解有一点怀疑,所以我想要一些意见。

在使用 C++ 开发应用程序时,我必须进行一些性能测试,最后我比较了 make_shared 和 shared_ptr+new(请注意,这不是提高性能的目的,我不希望在这里获得时间,但是我现在只是好奇)

我用

Debian Jessy x64 liboost 1.55 GCC 4.9.2

我读到 make_shared 效率更高,根据我能找到的解释(分配编号、开销),这对我来说似乎是合乎逻辑的(据我所知)。

但是做一个快速而愚蠢的测试,我不明白我得到了什么

        std::shared_ptr<MyUselessClass> dummyPtr = std::shared_ptr<MyUselessClass>(new MyUselessClass());
    auto start = boost::chrono::high_resolution_clock::now() ;

    // - STD Share
    std::shared_ptr<MyUselessClass> stdSharePtr = std::shared_ptr<MyUselessClass>(new MyUselessClass());
    auto stdSharePtrTime_1 = boost::chrono::high_resolution_clock::now() ;

    // - STD Make
    std::shared_ptr<MyUselessClass> stdMakePtr = std::make_shared<MyUselessClass>();
    auto stdMakePtrTime_2 = boost::chrono::high_resolution_clock::now() ;

    // - BOOST Share
    boost::shared_ptr<MyUselessClass> boostSharePtr = boost::shared_ptr<MyUselessClass>(new MyUselessClass());
    auto boostSharePtrTime_3 = boost::chrono::high_resolution_clock::now() ;

    // - BOOST Make
    boost::shared_ptr<MyUselessClass> boostMakePtr = boost::make_shared<MyUselessClass>();
    auto boostMakePtrTime_4 = boost::chrono::high_resolution_clock::now() ;

    boost::chrono::nanoseconds stdShare = boost::chrono::duration_cast<boost::chrono::nanoseconds>(stdSharePtrTime_1-start) ;
    boost::chrono::nanoseconds stdMake = boost::chrono::duration_cast<boost::chrono::nanoseconds>(stdMakePtrTime_2-stdSharePtrTime_1) ;
    boost::chrono::nanoseconds boostShare = boost::chrono::duration_cast<boost::chrono::nanoseconds>(boostSharePtrTime_3-stdMakePtrTime_2) ;
    boost::chrono::nanoseconds boostMake = boost::chrono::duration_cast<boost::chrono::nanoseconds>(boostMakePtrTime_4-boostSharePtrTime_3) ;

    cout << "---" << endl ;
    cout << "STD   share " << stdShare << endl ;
    cout << "BOOST share " << boostShare << endl ;
    cout << "STD   make " << stdMake << endl ;
    cout << "BOOST make " << boostMake << endl ;

MyUselessClass 是一个简单的类,具有 3 个类属性(sting、bool、int),并且只有构造函数和析构函数。

“结果”(我引用是因为它当然不是一个准确的测试)如下(我将它运行到一个循环中以进行多次迭代,平均给出相同的结果):

    STD   share 162 nanoseconds
    BOOST share 196 nanoseconds
    STD   make 385 nanoseconds
    BOOST make 264 nanoseconds

如果我相信我的测试,make_shared 比调用 share_ptr 和新实例稍慢。如果我将任何差异视为纳秒精度,我会预料到,相反......

所以现在我想知道:

也许我的测试太愚蠢了,纳秒顺序在这些操作中并不重要? 也许我在解释 make_shared 更好的性能时漏掉了一点? 也许我在测试中错过了一些(几个)点?

如果您对以下几点有一些答案,请不要犹豫:)

感谢

【问题讨论】:

你真的不想只测量一个创建共享指针的调用!?请在循环中分配大量指针并进行比较。 【参考方案1】:

尝试使用-O2 编译您的程序。我尝试在没有优化的情况下编译你的代码,我得到了相似的数字。之后,使用-O2 编译代码,make_shared 始终更快。顺便说一句,MyUselessClass 班级的大小也会影响时间的比例。

【讨论】:

好吧,你可能对我投了反对票,因为我没有提到循环。 make_shared 在循环 1000000 次后仍然比“share”慢。我真的相信优化级别是 OP 观察到 make_shared 比“share”慢的原因

以上是关于在我的测试中,make_shared(boost 或 stl)似乎比 shared_ptr+new 稍慢的主要内容,如果未能解决你的问题,请参考以下文章

使用 boost::make_shared 创建矢量元素无法正常工作

需要使用互斥锁显式定义的复制构造函数

我应该如何在 io_service 中解决这个问题?

终止正在运行的 boost 线程

Boost 安装在我的 Ubuntu 上的啥位置?

构建 Boost Python 调试