2012-10-17 129 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。爲什麼?我是否可以增加boost版本的性能,因爲C++ 11不適用於某些舊項目,因爲它們使用的是舊版本的Visual Studio?

下面是我的代碼片段,用於測試這些。 NB。您需要手動切換升壓& std。 NB。 「SimpleMSTimer.hpp」是我用於boost 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用標記'-O3'編譯進行最大化優化。 測試結果:

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

他們進行顯著更好,因爲升壓版本沒有更新爲使用右值引用,這使移動語義。而C++ 11版本確實使用移動語義。這意味着Boost版本不得不經常複製。如果您在預C++ 11編譯器上進行測試,您的目標庫(使用std::tr1::shared_ptr),它們的表現應該更相似。

+2

我認爲移動語義的使用幾乎肯定會有更好性能的原因,但shared_ptr不會複製指向的對象 - 它只是更新引用計數,當您必須執行此操作時會耗費一定的時間以線程安全的方式。 – hjhill

+0

@hjhill很可能他只是指被複制的'shared_ptr',而不是當他談論複製時指向的對象。 –

+0

@DeadMG:我一直在考慮移動語義效應,但這只是它嗎?另外在我的問題中,我問過是否可以提高shared_ptr,make_shared與C++ std版本相比具有更好/匹配的性能,您是否也可以回答這個問題? – Gob00st

相關問題