Le coût de passage par shared_ptr

J'utilise std::tr1::shared_ptr largement tout au long de ma demande. Cela inclut la transmission des objets comme arguments de la fonction. Considérez les points suivants:

class Dataset {...}

void f( shared_ptr< Dataset const > pds ) {...}
void g( shared_ptr< Dataset const > pds ) {...}
...

Tout en passant un objet dataset autour de la via shared_ptr garantit son existence à l'intérieur de f et g, les fonctions peuvent être appelées des millions de fois, ce qui provoque beaucoup de shared_ptr objets créés et détruits. Voici un extrait de l'appartement gprof profil à partir d'une récente:

Chaque échantillon compte que 0,01 secondes. 
% cumulatif total de soi 
secondes) (secondes les appels s/demande/appel nom 
9.74 295.39 35.12 2451177304 0.00 0.00 std::tr1::__shared_count::__shared_count(std::tr1::__shared_comte const&) 
8.03 324.34 28.95 2451252116 0.00 0.00 std::tr1::__shared_count::~__shared_count() 

Donc, ~17% de l'exécution a été dépensé sur le comptage de référence avec shared_ptr objets. Est-ce normal?

Une grande partie de mon application est mono-thread, et je pensais à ré-écrire certaines des fonctions que

void f( const Dataset& ds ) {...}

et en remplaçant les appels

shared_ptr< Dataset > pds( new Dataset(...) );
f( pds );

avec

f( *pds );

dans des endroits où je sais pour sûr, l'objet ne sera pas détruit, tandis que le flux du programme est à l'intérieur de f(). Mais avant de courir pour changer un tas de signatures de fonction /appels, je voulais savoir quelles sont les performances habituelles frappé de passer par shared_ptr a été. Semble comme shared_ptr ne doit pas être utilisé pour des fonctions qui appelés très souvent.

Toute entrée serait appréciée. Merci pour la lecture.

-Artem

Mise à jour: Après un changement de poignée de fonctions d'accepter const Dataset&, le nouveau profil ressemble à ceci:

Chaque échantillon compte que 0,01 secondes. 
% cumulatif total de soi 
secondes) (secondes les appels s/demande/appel nom 
0.15 241.62 0.37 24981902 0.00 0.00 std::tr1::__shared_count::~__shared_count() 
0.12 241.91 0.30 28342376 0.00 0.00 std::tr1::__shared_count::__shared_count(std::tr1::__shared_comte const&) 

Je suis un peu perplexe par le nombre d'appels de destructeur étant plus petite que le nombre de constructeur de copie d'appels, mais dans l'ensemble je suis très heureux avec la diminution de l'associé au moment de l'exécution. Merci à tous pour leurs conseils.

  • Question connexe: stackoverflow.com/questions/327573/...
  • Question connexe: sur certaines plates-formes (par exemple, âgés de BRAS), le comptage de référence nécessite de verrouiller un mutex. Cela peut faire partagé pointeurs inutilisable (sauf par référence) dans un réel contexte de temps.