Pourquoi std :: make_shared () a de bien meilleures performances que boost :: make_shared ()?

Je fais des tests de performance sur le terrain

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 

Le résultat du test est quelque peu intéressant.

1> En général, la version std fonctionne mieux mais surtout std::make_shared . Pourquoi? Puis-je augmenter les performances de la version boost car C ++ 11 n’est pas encore disponible pour certains anciens projets, car ils utilisent l’ancienne version de Visual studio?

Ci-dessous, mon extrait de code utilisé pour les tester. NB vous devez basculer manuellement entre boost & std. NB “SimpleMSTimer.hpp” est mon wrapper de timer pour boost ptime, un peu trop long à poster ici. Mais n’hésitez pas à utiliser votre propre timer. N’importe quel temps portable conviendrait.

 #include "stdafx.h" #include  #include  #include  #include  #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 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 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 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 thingPtrs; YiUtil::MSSegmentTimer segTimer(YiUtil::MSSegmentTimer::MLSEC, std::cout); for(int i=0; i< num; i++) { ThingPtr p1 = boost::make_shared(); 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(); 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; } 

Compilateur VC10 en mode release, gcc compilé avec le drapeau ‘-O3’ pour une optimisation maximale. Résultat du test:

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

Leurs performances sont nettement meilleures, car la version de Boost n’est pas mise à jour pour utiliser des références rvalue, qui permettent la sémantique du déplacement. Alors que les versions C ++ 11 utilisent la sémantique de déplacement. Cela signifie que la version de Boost doit copier un peu plus souvent. Si vous testez sur un compilateur antérieur à C ++ 11, votre base cible (avec std::tr1::shared_ptr ) devrait fonctionner de manière beaucoup plus similaire.