为什么的std :: make_shared<>()已性能比提升好得多:: make_shared()? [英] Why std::make_shared<>() has much better performance than boost::make_shared()?

查看:125
本文介绍了为什么的std :: make_shared<>()已性能比提升好得多:: make_shared()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在做一些现场性能测试上

  1 GT;的std :: shared_ptr的,性病::基于GCC 4.7.2'和make_shared; VC10实施'
2 - ;升压:: shared_ptr的,提振:: make_shared基础上提升1.47

测试结果是有点有趣。

1>一般 STD 版本执行得更好,但尤其是的std :: make_shared 。为什么?我可以增加升压版本的性能,因为C ++ 11不适用于一些老项目又因为他们使用的是旧版本的Visual Studio?

下面是一个用来测试那些我的code片段。
NB。你需要提升和放大器之间手动切换;性病。
NB。 SimpleMSTimer.hpp是我升压分组时间定时器包装,有点太长,张贴在这里。但随意使用自己的timer.Any便携式时候会怎么做。

 的#includestdafx.h中
#包括LT&;矢量>
#包括LT&;&iostream的GT;
#包括LT&;升压/ shared_ptr.hpp>
#包括LT&;升压\\ make_shared.hpp>#包括SimpleMSTimer.hpp//我的定时器的包装升压的ptime使用命名空间std;
使用名字空间boost;类的事
{
上市:
    事情()
    {
    }    无效的方法(无效)
    {
        INT I = 5;
    }
};TYPEDEF提高:: shared_ptr的<&东西GT; ThingPtr;无效processThing(事*的东西)
{
    东西─>的方法();
}//循环1循环2和测试的shared_ptr的载体容器
无效循环1(长长NUM)
{
    COUT<< 本土原始指针;
    矢量<&东西GT; thingPtrs;
    YiUtil :: MSSegmentTimer segTimer(YiUtil :: MSSegmentTimer :: MLSEC,性病::法院);
    的for(int i = 0; I<民;我++){
        事情的事;
        thingPtrs.push_back(事);
    }
    thingPtrs.clear();
}无效循环2(长长NUM)
{
    COUT<< 本土的boost :: shared_ptr的:;
    矢量< ThingPtr> thingPtrs;
    YiUtil :: MSSegmentTimer segTimer(YiUtil :: MSSegmentTimer :: MLSEC,性病::法院);
    的for(int i = 0; I<民;我++){
        ThingPtr P1(新事物);
        thingPtrs.push_back(P1);
    }
}无效循环3(长长NUM)
{
    COUT<< 优化的boost :: shared_ptr的:;
    矢量< ThingPtr> thingPtrs;    YiUtil :: MSSegmentTimer segTimer(YiUtil :: MSSegmentTimer :: MLSEC,性病::法院);
    的for(int i = 0; I<民;我++){
        ThingPtr P1 =提振:: make_shared<&东西GT;();
        thingPtrs.push_back(P1);
    }
}
//循环3和循环4 shared_ptr的测试循环中
无效循环4(长长NUM)
{
    COUT<< 本土原始指针;
    YiUtil :: MSSegmentTimer segTimer(YiUtil :: MSSegmentTimer :: MLSEC,性病::法院);
    的for(int i = 0; I<民;我++){
        事* P1 =新事物();
        processThing(P1);
        删除P1;
    }
}无效loop5(长长NUM)
{
    COUT<< 本土的boost :: shared_ptr的:;
    YiUtil :: MSSegmentTimer segTimer(YiUtil :: MSSegmentTimer :: MLSEC,性病::法院);
    的for(int i = 0; I<民;我++){
        ThingPtr P1(新事物);
        processThing(p1.get());
    }
}无效loop6(长长NUM)
{
    COUT<< 优化的boost :: shared_ptr的:;
    YiUtil :: MSSegmentTimer segTimer(YiUtil :: MSSegmentTimer :: MLSEC,性病::法院);
    的for(int i = 0; I<民;我++){
        ThingPtr P1 =提振:: make_shared<&东西GT;();
        processThing(p1.get());
    }
}诠释主(){
    长长的NUM =千万;
    COUT<< 测试1<< ENDL;
    循环1(NUM);
    循环2(NUM);
    循环3(NUM);    COUT<< 测试2<< ENDL;
    循环4(NUM);
    loop5(NUM);
    loop6(NUM);    返回0;
}

在释放模式VC10编译器gcc编译标志-O3'的最大优化。
测试结果:

  // VS2010发布模式
//促进
测试1
本地原始指针:SegmentTimer:15毫秒/ N
原生的boost :: shared_ptr的:SegmentTimer:3312毫秒/ N
优化的boost :: shared_ptr的:SegmentTimer:3093毫秒/ N
测试2
本地原始指针:SegmentTimer:921毫秒/ N
原生的boost :: shared_ptr的:SegmentTimer:2359毫秒/ N
优化的boost :: shared_ptr的:SegmentTimer:2203毫秒/ N// STD
测试1
本地原始指针:SegmentTimer:15毫秒/ N
原生的std :: shared_ptr的:SegmentTimer:3390毫秒/ N
优化的std :: shared_ptr的:SegmentTimer:2203毫秒/ N
测试2
本地原始指针:SegmentTimer:937毫秒/ N
原生的std :: shared_ptr的:SegmentTimer:2359毫秒/ N
优化的std :: shared_ptr的:SegmentTimer:1343毫秒/ N
================================================== ============================
GCC 4.72释放模式
//促进
测试1
本地原始指针:SegmentTimer:15毫秒/ N
原生的boost :: shared_ptr的:SegmentTimer:4874毫秒/ N
优化的boost :: shared_ptr的:SegmentTimer:3687毫秒/ N
测试2
本地原始指针:SegmentTimer:1109毫秒/ N
原生的boost :: shared_ptr的:SegmentTimer:2546毫秒/ N
优化的boost :: shared_ptr的:SegmentTimer:1578毫秒/ N// STD
测试1
本地原始指针:SegmentTimer:15毫秒/ N
原生的std :: shared_ptr的:SegmentTimer:3374毫秒/ N
优化的std :: shared_ptr的:SegmentTimer:2296毫秒/ N
测试2
本地原始指针:SegmentTimer:1124毫秒/ N
原生的std :: shared_ptr的:SegmentTimer:2531毫秒/ N
优化的std :: shared_ptr的:SegmentTimer:1468毫秒/ N


解决方案

他们执行显著更好,因为升压版本没有更新为使用右值引用,它使移动语义。而C ++ 11的版本确实使用了移动语义。这意味着,升压版本具有更频繁地复制了不少。如果您在pre-C ++编译器11测试,你的目标的基础(以的std :: TR1的:: shared_ptr的),他们应该更类似地进行。

I have been doing some field performance test on

1>std::shared_ptr, std::make_shared based on 'gcc 4.7.2' & 'VC10 implementation' 
2>boost::shared_ptr, boost::make_shared based on boost 1.47

The test result is somewhat interesting.

1>In general std version performs better but especially std::make_shared. Why? Can I increase the boost version performance since C++ 11 is not available for some old project yet as they are using old version of Visual studio?

Below is my code snippet used to test those. NB. you need to manually switch between boost & std. NB. "SimpleMSTimer.hpp" is my timer wrapper for boost ptime, a bit too long to post here. But feel free to use your own timer.Any portable time would do.

#include "stdafx.h"
#include <vector>
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost\make_shared.hpp>

#include "SimpleMSTimer.hpp"//my timer wrapper for boost ptime

using namespace std;
using namespace boost;

class Thing
{
public:
    Thing()
    {
    }

    void method (void)
    {
        int i = 5;
    }
};

typedef boost::shared_ptr<Thing> ThingPtr;

void processThing(Thing* thing)
{
    thing->method();
}

//loop1 and loop2 test shared_ptr in the vector container
void loop1(long long num)
{
    cout << "native raw pointer: ";
    vector<Thing> thingPtrs;
    YiUtil::MSSegmentTimer segTimer(YiUtil::MSSegmentTimer::MLSEC, std::cout);
    for(int i=0; i< num; i++) {
        Thing thing;
        thingPtrs.push_back(thing);
    }
    thingPtrs.clear();
}

void loop2(long long num)
{
    cout << "native boost::shared_ptr: ";
    vector<ThingPtr> thingPtrs;
    YiUtil::MSSegmentTimer segTimer(YiUtil::MSSegmentTimer::MLSEC, std::cout);
    for(int i=0; i< num; i++) {
        ThingPtr p1(new Thing);
        thingPtrs.push_back(p1);
    }
}

void loop3(long long num)
{
    cout << "optimized boost::shared_ptr: ";
    vector<ThingPtr> thingPtrs;

    YiUtil::MSSegmentTimer segTimer(YiUtil::MSSegmentTimer::MLSEC, std::cout);
    for(int i=0; i< num; i++) {
        ThingPtr p1 = boost::make_shared<Thing>();
        thingPtrs.push_back(p1);
    }
}


//loop3 and loop4 test shared_ptr in loop
void loop4(long long num)
{
    cout << "native raw pointer: ";
    YiUtil::MSSegmentTimer segTimer(YiUtil::MSSegmentTimer::MLSEC, std::cout);
    for(int i=0; i< num; i++) {
        Thing* p1 = new Thing();
        processThing(p1);
        delete p1;
    }
}

void loop5(long long num)
{
    cout << "native boost::shared_ptr: ";
    YiUtil::MSSegmentTimer segTimer(YiUtil::MSSegmentTimer::MLSEC, std::cout);
    for(int i=0; i< num; i++) {
        ThingPtr p1(new Thing);
        processThing(p1.get());
    }
}

void loop6(long long num)
{
    cout << "optimized boost::shared_ptr: ";
    YiUtil::MSSegmentTimer segTimer(YiUtil::MSSegmentTimer::MLSEC, std::cout);
    for(int i=0; i< num; i++) {
        ThingPtr p1 = boost::make_shared<Thing>();
        processThing(p1.get());
    }
}

int main() {
    long long num = 10000000;
    cout << "test 1" << endl;
    loop1(num);
    loop2(num);
    loop3(num);

    cout << "test 2"<< endl;
    loop4(num);
    loop5(num);
    loop6(num);

    return 0;
}

VC10 compiler under release mode, gcc compiled with flag '-O3' for max optimization. Test result:

//VS2010 release mode
//boost
test 1
native raw pointer: SegmentTimer: 15 milliseconds/n
native boost::shared_ptr: SegmentTimer: 3312 milliseconds/n
optimized boost::shared_ptr: SegmentTimer: 3093 milliseconds/n
test 2
native raw pointer: SegmentTimer: 921 milliseconds/n
native boost::shared_ptr: SegmentTimer: 2359 milliseconds/n
optimized boost::shared_ptr: SegmentTimer: 2203 milliseconds/n

//std
test 1
native raw pointer: SegmentTimer: 15 milliseconds/n
native std::shared_ptr: SegmentTimer: 3390 milliseconds/n
optimized std::shared_ptr: SegmentTimer: 2203 milliseconds/n
test 2
native raw pointer: SegmentTimer: 937 milliseconds/n
native std::shared_ptr: SegmentTimer: 2359 milliseconds/n
optimized std::shared_ptr: SegmentTimer: 1343 milliseconds/n
==============================================================================
gcc 4.72 release mode
//boost
test 1
native raw pointer: SegmentTimer: 15 milliseconds/n
native boost::shared_ptr: SegmentTimer: 4874 milliseconds/n
optimized boost::shared_ptr: SegmentTimer: 3687 milliseconds/n
test 2
native raw pointer: SegmentTimer: 1109 milliseconds/n
native boost::shared_ptr: SegmentTimer: 2546 milliseconds/n
optimized boost::shared_ptr: SegmentTimer: 1578 milliseconds/n

//std
test 1
native raw pointer: SegmentTimer: 15 milliseconds/n
native std::shared_ptr: SegmentTimer: 3374 milliseconds/n
optimized std::shared_ptr: SegmentTimer: 2296 milliseconds/n
test 2
native raw pointer: SegmentTimer: 1124 milliseconds/n
native std::shared_ptr: SegmentTimer: 2531 milliseconds/n
optimized std::shared_ptr: SegmentTimer: 1468 milliseconds/n

解决方案

They perform significantly better because the Boost version is not updated to use rvalue references, which enable move semantics. Whereas the C++11 versions do use move semantics. This means that the Boost version is having to copy quite a bit more often. If you test on a pre-C++11 compiler, your target base (with std::tr1::shared_ptr) they should perform much more similarly.

这篇关于为什么的std :: make_shared&LT;&GT;()已性能比提升好得多:: make_shared()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆