2012-10-17 2 views
4

내가 시험 결과왜 std :: make_shared <>()가 boost :: make_shared()보다 훨씬 뛰어난 성능을 제공합니까?

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 

일부 현장 성능 시험을하고있다 다소 흥미 롭다.

1> 일반적으로 std 버전이 더 좋지만 특히 std::make_shared입니다. 왜? 이전 버전의 Visual Studio를 사용하고 있기 때문에 일부 이전 프로젝트에서 C++ 11을 사용할 수 없으므로 boost 버전 성능을 향상시킬 수 있습니까?

다음은 이러한 코드를 테스트하는 데 사용되는 코드입니다. NB. 부스트 & 표준 사이를 수동으로 전환해야합니다. NB. "SimpleMSTimer.hpp"는 부스트 ptime에 대한 나의 타이머 래퍼이며 여기에 게시하기에는 너무 길다. 그러나 당신의 자신의 타이머를 자유롭게 사용하십시오. 어떤 휴대용 시간든지 할 것입니다. 릴리스 모드에서

#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 컴파일러는 GCC 플래그로 컴파일 '-03'최대 최적화. 시험 결과 :

//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 
+2

벤치 마크를 몇 번이나 실행 했습니까? 벤치 마크 순서를 변경하려고 시도 했습니까? std :: shared_ptr 및 boost :: shared_ptr에 대한 소스를 살펴 보셨습니까? –

+1

이것은 벤치 마크 테스트가 아니므로이 테스트에 대한 판단을 삼가해야합니다. – DumbCoder

+0

'boost 1.47'는 꽤 오래되었습니다.'boost 1.51'을 시도해보십시오. C++ 11 지원으로 업데이트해야합니다. –

답변

2

그들은 부스트 ​​버전이 이동 의미를 활성화를 rvalue 참조를 사용하도록 업데이트되지 않기 때문에 훨씬 더 나은 수행합니다. 반면 C++ 11 버전에서는 이동 의미를 사용합니다. 이것은 Boost 버전이 꽤 자주 복사해야한다는 것을 의미합니다. pre-C++ 11 컴파일러에서 테스트 할 경우 대상베이스 (std::tr1::shared_ptr 포함)는 훨씬 비슷하게 수행해야합니다.

+2

나는 move semantics를 사용하는 것이 성능 향상의 이유라고 생각 하겠지만 shared_ptr은 가리키는 객체를 복사하지 않는다. 참조 횟수를 업데이트하기 때문에 시간이 많이 걸린다. 스레드로부터 안전한 방식으로. – hjhill

+0

@hjhill 그가 shared_ptr을 복사하는 것을 언급했을뿐 아니라 여기에서 복사하는 것에 대해 이야기 할 때 객체를 가리 키지 않았을 가능성이 큽니다. –

+0

@DeadMG : 나는 이동 의미론 효과를 고려해 왔지만, 그것은 단지 그것일까요? 또한 내 질문에, 나는 부스트 shared_ptr 만들 수 있습니다, make_shared 더 나은/C + + 표준 버전으로 성능 일치, 당신은뿐만 아니라 대답 할 수 있습니까? – Gob00st

관련 문제