7
votes

C ++ COUT Impression lentement

J'ai remarqué si j'imprime une chaîne longue (char *) à l'aide de COUT, il semble imprimer 1 caractère à la fois à l'écran de Windows 7, Vista et Linux (à l'aide de PUTTY) à l'aide de Visual C ++ 2008 sur Windows et G ++. sur Linux. Printf est tellement plus rapide que je réalise en fait de COUT à PrintF pour la plupart des impressions dans un projet de mien. Cela me confondre parce que cette Question montre que je suis le seul à avoir ce problème.

J'ai même écrit un remplacement de cout qui ressemble à ce que cela bat le pantalon off de Cout sur ma comp- xxx

Des idées Pourquoi coutes est-elle une impression si lentement pour moi?


4 commentaires

Je l'ai encore essayé sur l'ordinateur Linux, et COUT et RCOUT semblaient avoir la même vitesse, mais je sais que COUT était beaucoup plus lent que Printf dans mon autre application, donc je pense que cela pourrait être limité? Ensuite, je l'ai essayé sur My Vista Comp et Cout a pris environ 375 ms tandis que RCout a pris environ 100 ms. Sur Windows 7 Comp Cout a pris 850 ms et RCout a pris environ 70 ms.


<< endl ? COUT ne fligeons automatiquement. Il est possible que vous exécutez dans Windows tamponner les données différemment de ce qu'il ne le fait pour printf . Essayez également CERR au lieu de COUT et voyez si cela fait une différence: si cela fait le rinçage est définitivement le problème.


Cerr a effectué la même chose que cout, fait également une affleurance () après que la cout n'aidait pas


Il semble que Visual Studio est à blâmer pour la coude lente, mais j'ai eu cette application Linux qui imitait lentement avec Cout et je l'ai commutée à Printf et qui lui a fixé. Dans cette application, j'utilisais des coutures vraiment simples, surtout seulement quelque chose comme Cout << tampon; Je suppose que c'est parce qu'il y avait 8 threads utilisant Cout, peut-on confirmer ce problème?


8 Réponses :


9
votes

Je vous suggère d'essayer ce même test sur un autre ordinateur. Je n'ai pas de bonne réponse pour pourquoi cela pourrait se produire; Tout ce que je peux dire, c'est que je n'ai jamais remarqué une différence de vitesse entre Cout et Printf. J'ai également testé votre code à l'aide de GCC 4.3.2 sur Linux et il n'y avait aucune différence que ce soit.

qui étant dit, vous ne pouvez pas facilement remplacer la cout avec votre propre implémentation. Le fait est que Cout est une instance de std :: ostream qui a beaucoup em> de fonctionnalités intégrées à celle qui est nécessaire pour l'interopérabilité avec d'autres classes qui surchargent les opérateurs iostream. P>

edit: strong> p>

Quelqu'un qui dit printf code> est toujours plus rapide que std :: cout code> est simplement mal. Je viens de courir le code de test posté par Minjang, avec GCC 4.3.2 et le drapeau -O2 sur un AMD AMD ATHLON X2 de 64 bits, et COUT était en fait plus vite em>. P>

J'ai les résultats suivants: p>

printf: 00:00:12.024
cout:   00:00:04.144


4 commentaires

J'ai également testé sur Linux avec ICC -O3 sur la machine Xeon. Mesurée par temps et mettre > / dev / null . Dans quelque cas, COUT nécessite plus d'instructions à remplir. Mais, les différences sont petites. Par exemple, COUT 0.311 VS Printf 0.218. Mais, j'entends absolument que cela dépend de la mise en œuvre. J'ai édité ma réponse.


@minjang je pense que le test pourrait être plus significatif si vous n'envoyez pas stdout à dev / null


@Ramonster, printf toujours plus rapide. Quelques détails: compilés par g ++ w / -o3. COUT a pris 4,9 secondes, mais Printf a pris 4,5 secondes. Pas une grande différence cependant. Mais, # d'instructions exécutées sont de 775m pour COUT, 589m pour Printf. En fait, 200 millions de différences dans les processeurs modernes sont assez petites. De plus, je dois supposer que chaque instruction prendrait une heure similaire (je sais que ce n'est pas si raisonnable). Quoi qu'il en soit, dans mon expérimentation, Printf était plus rapide sur Linux et Windows.


Classe RCOUT {Public: Modèle RCOUT & OPLOCICE << (A A) {STRINGSTREAM SS; ss << (a); fwrite (Ss.str (). C_STR (), 1, SS.Str (). Longueur (), stdout); retour (* this); }}; Rcout rcout; int Main () {RCOUT << "C'est assez bon, le fil de fil aussi \ n"; retour 0; }



0
votes

Essayez d'utiliser quelques endl s ou Flush ES comme ils vont flush < CODE> COUT S TIMBER, au cas où le système d'exploitation met en cache la sortie de votre programme pour une raison quelconque. Mais, comme le dit Charles, il n'y a pas de bonne explication de ce comportement, alors si cela n'aide pas, il est probablement un problème spécifique à votre machine.


1 commentaires

J'ai essayé d'utiliser Endl et Flush (), ils ne semblent pas faire la différence. J'ai chronométré l'impression et a obtenu 842 ms pour COUT et 63 ms pour mon RCOUT



1
votes

Basé sur mon expérience dans les compétitions de programmation, Printf est plus rapide que Cout.

Je me souviens de plusieurs reprises lorsque ma solution ne l'a pas fait avant la limite de temps juste à cause de Cin / COUT , tandis que printf / scanf a fonctionné.

En plus de cela, il semble normal (au moins pour moi) que cout est plus lent que printf , car il fait plus d'opérations.


1 commentaires

Il ne devrait jamais être que beaucoup plus lentement, dans la mesure décrite par l'OP.



12
votes

note : ce résultat expérimental est valide pour MSVC. Dans une autre implémentation de la bibliothèque, le résultat variera.

printf pourrait être être (beaucoup) plus rapide que Cout . Bien que printf analyse la chaîne de format au moment de l'exécution, il nécessite des appels de fonction beaucoup moins et nécessite un petit nombre d'instructions pour effectuer un même travail, en comparant à COUT . Voici un résumé de mon expérimentation:

le nombre d'instructions statiques

en général, COUT génère beaucoup de code que printf . Disons que nous avons le code suivant COUT pour imprimer avec certains formats. xxx

sur un compilateur VC ++ avec des optimisations, il génère autour de 188 code d'octets. Mais, lorsque vous remplacez le code printf -Based, seuls 42 sont requis.

le nombre d'instructions exécutées dynamiquement

Le nombre d'instructions statiques indique simplement la différence de code binaire statique. Ce qui est plus important, c'est le nombre réel d'instructions exécutées de manière dynamique en runtime. J'ai aussi fait une simple expérimentation:

code de test: xxx

ici est le résultat de Test1 (COUT):

  • Nombre d'instructions exécutées: 423,234 439
  • # de la mémoire charge / magasins: env. 320 000 et 980 000
  • temps écoulé: 52 secondes

    Ensuite, qu'en est-il de printf ? Ceci est le résultat de Test2:

    • Nombre d'instructions exécutées: 164 800 800
    • # de la mémoire charge / magasins: env. 70 000 et 180 000
    • temps écoulé: 13 secondes

      dans cette machine et compilateur, printf était beaucoup plus rapide cout . Dans les deux instructions exécutées, et que # de charge / magasin (indique le nombre de cache misses) ont 3 ~ 4 fois différences.

      Je sais que c'est un cas extrême. De plus, je dois noter que COUT est beaucoup plus facile lorsque vous gérez des données 32/64 bits et nécessitent une indépendance 32/64-Plateforme. Il y a toujours un compromis. J'utilise COUT lorsque le type de vérification est très délicat.

      ok, COUT in msvs est juste cyclable :)


4 commentaires

Ce n'est pas correct; COUT n'est pas toujours plus rapide que printf par n'importe quel moyen. Voir mon post pour plus de détails.


J'ai corrigé ma réponse. Mais mes expériences sur Windows / Linux donnent toujours la cohérence. COUT est plus lent que printf . J'ai aussi compté le nombre d'instructions exécutées. Oui, COUT NÉCESSAIRE MOWERN PrintF . Dans Linux, 20% d'autres instructions étaient nécessaires pour Cout .


Réponse choisie pour "D'accord, COUT IN MSVS SUCKS SUCKS :)", tu as raison, c'est le problème


Maintenant, nous avons reçu la réponse de Microsoft Connect - "Il s'agit d'une malheureuse conséquence de la manière dont nos implémentations de bibliothèque standard C et C ++ sont conçues". Voir connect.microsoft.com/visualstudio/feedback/Détails/642876/...



-2
votes

Voici HAX qui devrait faire des flux C ++ aussi vite que c Printf. Je ne l'ai jamais testé mais je crois que ça marche. XXX


0 commentaires

4
votes

Essayez appeler iOS :: Sync_with_stdio (faux); Avant d'utiliser STD :: COUT / CIN, sauf si bien sûr, vous mélangez STDIO et iOSTREAM dans votre programme, ce qui est une mauvaise chose à faire.


2 commentaires

Cela ne semblait pas faire une différence


Êtes-vous sûr que vous utilisez la construction «version / optimisation»? iostream a tendance à être beaucoup plus lent en mode de débogage en raison du code de modèle.



0
votes

Vous devriez essayer d'écrire toutes vos données à un ostringstream code> d'abord, puis utilisez COUT code> sur le ostringstream code> 's str () code>. Je suis sur 64 bits Windows 7 et Test1 Code> était déjà significativement plus rapide que Test2 code> (Votre kilométrage peut varier). Utilisation d'un ostringingstream code> Pour créer une seule chaîne d'abord, puis à l'aide de COUT code> sur ce a diminué supplémentaire i> Test1 code> par un facteur d'environ 3 à 4. Assurez-vous de #include code>.

c'est-à-dire, remplacez p> xxx pre>

avec: P>

void Foo1()
{
    for(int i = 0; i < 10000; ++i) {
        cout << "Foo1\n";
    }
}

void Foo2()
{
    std::string s;
    for(int i = 0; i < 10000; ++i) {
        s += "Foo2\n";
    }
    cout << s;
}

void Foo3()
{
    std::ostringstream oss;
    for(int i = 0; i < 10000; ++i) {
        oss << "Foo3\n";
    }
    cout << oss.str();
}


0 commentaires

0
votes

Essayez d'utiliser iOS :: sync_with_stdio (faux); . Mentionnez-le avant d'utiliser STD :: CIN / COUT. Il ne mélange pas stdio ou iostream, mais elle synchronise des flux standard iostream avec leurs flux de standard C correspondant. Par exemple - STD :: CIN / WCIN OF IOSTREAM est synchronisé avec STDIN of C Stream


0 commentaires