2012-10-17 130 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

相关问题