9
votes

Pourquoi utiliser STD :: endl avec Ostringstream affecte la vitesse de sortie?

Je tire la différence entre différentes manières d'imprimer du texte à la sortie standard. Je teste cout code>, printf code> et ostringstream code> à l'aide des deux \ n code> et std :: endl code>. Je m'attendais à std :: endl code> pour faire une différence avec COUT code> (et cela a fait), mais je ne m'attendais pas à ralentir la sortie avec OstringingStream code>. Je pensais utiliser std :: endl code> n'écrirait pas un \ n code> au flux et il ne serait toujours pas flushé une fois. Que se passe t-il ici? Voici tout mon code:

time ./cout.out > output.txt

real    0m1.771s
user    0m0.616s
sys 0m0.148s
time ./printf.out > output.txt

real    0m2.411s
user    0m0.392s
sys 0m0.172s
time ./stream.out > output.txt

real    0m2.048s
user    0m0.632s
sys 0m0.220s
time ./streamn.out > output.txt

real    0m1.742s
user    0m0.404s
sys 0m0.200s


3 Réponses :


14
votes

std :: endl déclenche une flush du flux, qui ralentit une impression beaucoup. Voir http://fr.cpppreference.com/w/cpp/io/manip/endl

Il est souvent recommandé de ne pas utiliser std :: endl sauf si vous voulez vraiment que le flux soit rincé. Si cela est vraiment important pour vous, dépend de votre cas d'utilisation.

Concernant pourquoi Flush a un impact sur la performance même sur un Ostringstream (où aucun rinçage ne devrait arriver): il semble que une implémentation soit nécessaire pour construire au moins les objets sentinels. Ceux-ci doivent vérifier bon et Cravate du ostream . L'appel à pubsync devrait pouvoir être optimisé. Ceci est basé sur ma lecture de libcpp et de libstdc ++.

Après plus de lecture, la question intéressante semble être ceci: est une implémentation de basic_ostringstream :: flush vraiment nécessaire pour construire l'objet Sentry? Sinon, cela ressemble à une "qualité de mise en œuvre". Mais je pense en fait que cela a besoin, car même un basic_stringbug peut changer pour avoir son Badbit SET.


2 commentaires

En fait, je savais que, mais je ne savais pas que cela affectait la performance de Stringstream. Rincer Couts signifie émettre ce qui est dans la mémoire tampon de sortie, que signifie rincer StringStream? Quelle est la sortie que le texte se fait rougir?


@ gsingh2011 c'est ce que je penserais. Mais basic_ostringstream a en fait basic_stringbuf ci-joint et est requis pour construire la sentinelle mentionnée dans la documentation de Flush .



0
votes

Utiliser std :: endl équivaut à écrire xxx

n'utilise pas std :: endl sauf si vous ne voulez pas réellement déclencher le rinçage et / ou ne se soucient pas des performances de sortie.

En outre, ne vous inquiétez pas des extrémités de ligne différentes sur différentes plates-formes, votre implémentation traduira "\ n" à la ligne de ligne appropriée pour votre plate-forme. < / p>


0 commentaires

1
votes

Chaque opération de sortie sur un flux dors plusieurs étapes:

  • Il vérifie si le flux est en bonne forme.
  • Il vérifie si un autre flux a besoin de rougir.
  • La séquence de caractères est produite.
  • Il vérifie s'il y a suffisamment d'espace pour les caractères écrits.
  • L'utilisation de endl appelle une fonction virtuelle supplémentaire sur le tampon de flux.

    J'attendrais personnellement que l'appel de la fonction virtuelle supplémentaire ait réellement un impact relativement faible par rapport aux autres opérations. Vous pouvez vérifier cette hypothèse en profilant également cette sortie: xxx

    ... ou même xxx

    qui dit, sont un certain nombre d'améliorations qu'une implémentation de flux peut s'appliquer pour réduire les chèques. Si cela est fait dépendra de la mise en œuvre, bien sûr.


0 commentaires