OVH Cloud OVH Cloud

cout ou printf

14 réponses
Avatar
Jean-Michel Caricand
Bonjour à tous,

J'aurais une question très simple. Quel est e plus rapide entre un
affichage avec cout ou avec printf. En lisant l'ouvrage "La qualité en
C++" de Philippe Prados j'ai l'impression que l'utilisation de cout
devrait donner un résultat plus rapide car optimisé. Néanmoins,
certaines lectures faites sur le Net indique que printf est plus rapide.

Qui croire ?

Merçi pour vos réponses.

10 réponses

1 2
Avatar
Alexandre
pour te faire une idée, tu peux faire le test toi même : dans une boucle
fais 100000 printf puis 100000 cout, avec mesure du temps (voir suivant ton
os) , mais AMA ce n'est pas significatif.
Avatar
kanze
Alexandre wrote:

pour te faire une idée, tu peux faire le test toi même : dans
une boucle fais 100000 printf puis 100000 cout, avec mesure du
temps (voir suivant ton os) , mais AMA ce n'est pas
significatif.


Surtout, il va dépendre beaucoup de l'implémentation, et de ce
que tu sors. Si à chaque coup, tu répètes des setw,
setprecision, etc., pour sortir un double, il y a des chances
que le résultat ne soit pas le même que si tu sors une chaîne
tout simple.

Évidemment, la plupart du temps, on sort des types définis par
l'utilisateur. Et alors, la question ne se pose même pas : c'est
possible avec les iostream, impossible avec printf. Aussi,
c'est assez fréquent de sortir vers un streambuf personel ; une
autre chose qui est impossible avec les flux de C.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Avatar
JBB
pour te faire une idée, tu peux faire le test toi même : dans une boucle
fais 100000 printf puis 100000 cout, avec mesure du temps (voir suivant ton
os) , mais AMA ce n'est pas significatif.


Lorsque tu fais :

printf("%s blablabla %d %d %s", s1,i1,i2,s2);
ton programme doit parser la chaine de format à l'execution
alors que dans le cas du cout le probleme est reglé des la compilation.
cout << s1 << " blablabla" << i1 << " " << i2 << " " << s2;

le printf pose d'autre problemes:
si tu fait
int i1 = 0;
printf ("%s",i1);
ca compile mais c'est sur que ça va planter à l'execution.

avec cout << i1; pas de probleme.

autre avantage lors de la modification de code:
cout << age_du_capitaine ;
marche quelque soit le type de age_du_capitaine int,double, string
ou même ta propre class du moment que tu a redefini la fonction qui va bien.

encore un piege :
char * s ;
...
printf(s);
en fait il faudrait faire printf("%s",s)
car pour peu que ta string s contienne un "%" tu risque d'avoir des
phenemones bizarres.
de plus ecrir printf(s) oblige le programme à parser s à la recherche de
% (donc moins performant).

En conclusion, je te conseille fortement de bannir le printf ainsi que
les char * d'ailleurs qui sont des reliques du C.

Avatar
Pierre Maurette
pour te faire une idée, tu peux faire le test toi même : dans une boucle
fais 100000 printf puis 100000 cout, avec mesure du temps (voir suivant ton
os) , mais AMA ce n'est pas significatif.


Lorsque tu fais :

printf("%s blablabla %d %d %s", s1,i1,i2,s2);
ton programme doit parser la chaine de format à l'execution
alors que dans le cas du cout le probleme est reglé des la compilation.
cout << s1 << " blablabla" << i1 << " " << i2 << " " << s2;

le printf pose d'autre problemes:
si tu fait
int i1 = 0;
printf ("%s",i1);
ca compile mais c'est sur que ça va planter à l'execution.

avec cout << i1; pas de probleme.

autre avantage lors de la modification de code:
cout << age_du_capitaine ;
marche quelque soit le type de age_du_capitaine int,double, string
ou même ta propre class du moment que tu a redefini la fonction qui va bien.

encore un piege :
char * s ;
...
printf(s);
en fait il faudrait faire printf("%s",s)
car pour peu que ta string s contienne un "%" tu risque d'avoir des
phenemones bizarres.
de plus ecrir printf(s) oblige le programme à parser s à la recherche de %
(donc moins performant).

En conclusion, je te conseille fortement de bannir le printf ainsi que les
char * d'ailleurs qui sont des reliques du C.
Tout celà me semble frappé au coin du bon sens. Je me permets une

question supplémentaire : quelqu'un qui ajourd'hui apprend C++ et qui
resterait dans une optique de code neuf (voeux pieux) peut-il faire
l'économie de l'apprentissage de printf() et consorts ? En particulier
pour son avatar sprintf(), cette fonction et sa chaîne de format
reste-t-elle indispensable ?

--
Pour répondre directement: enlever une lettre sur deux
wwaannaaddoooo -> wanadoo

Pierre Maurette


Avatar
JBB


pour te faire une idée, tu peux faire le test toi même : dans une
boucle fais 100000 printf puis 100000 cout, avec mesure du temps
(voir suivant ton os) , mais AMA ce n'est pas significatif.


Lorsque tu fais :

printf("%s blablabla %d %d %s", s1,i1,i2,s2);
ton programme doit parser la chaine de format à l'execution
alors que dans le cas du cout le probleme est reglé des la compilation.
cout << s1 << " blablabla" << i1 << " " << i2 << " " << s2;

le printf pose d'autre problemes:
si tu fait
int i1 = 0;
printf ("%s",i1);
ca compile mais c'est sur que ça va planter à l'execution.

avec cout << i1; pas de probleme.

autre avantage lors de la modification de code:
cout << age_du_capitaine ;
marche quelque soit le type de age_du_capitaine int,double, string
ou même ta propre class du moment que tu a redefini la fonction qui va
bien.

encore un piege :
char * s ;
...
printf(s);
en fait il faudrait faire printf("%s",s)
car pour peu que ta string s contienne un "%" tu risque d'avoir des
phenemones bizarres.
de plus ecrir printf(s) oblige le programme à parser s à la recherche
de % (donc moins performant).

En conclusion, je te conseille fortement de bannir le printf ainsi que
les char * d'ailleurs qui sont des reliques du C.


Tout celà me semble frappé au coin du bon sens. Je me permets une
question supplémentaire : quelqu'un qui ajourd'hui apprend C++ et qui
resterait dans une optique de code neuf (voeux pieux) peut-il faire
l'économie de l'apprentissage de printf() et consorts ? En particulier
pour son avatar sprintf(), cette fonction et sa chaîne de format
reste-t-elle indispensable ?

On peut eviter le sprintf avec un stringstream qui fonctionne comme

cout, mais ecrit dans un string au lieu de la sortie standard.
C'est vrai que c'est un parfois un peu lourd ( le sprintf parait plus
simple à utiliser).
Par contre ca evite les problemes du depassement de buffer.
( genre: char entier[5]; sprintf (entier,"%d",n); //le progamme plante
quand n > 9999 mais seulement en release... )

Le stringstream permet aussi de remplacer le sscanf.
( stringstream s; int i1,i2,i3; s << " 1 2 3"; s >> i1 >> i2 >> i3; )

Dans boost il existe des solutions pour les formats genre "%s %d" en
utilisant des stream, et les expression regulieres pour la lecture.



Avatar
JBB
Bonjour à tous,

J'aurais une question très simple. Quel est e plus rapide entre un
affichage avec cout ou avec printf. En lisant l'ouvrage "La qualité en
C++" de Philippe Prados j'ai l'impression que l'utilisation de cout
devrait donner un résultat plus rapide car optimisé. Néanmoins,
certaines lectures faites sur le Net indique que printf est plus rapide.

Qui croire ?

Merçi pour vos réponses.


Dernière remarque:
lors d'un cout ou d'un printf le fait d'ecrire reellement sur la console
(ou dans un fichier avec printf ou ofstream << ) prend beaucoup plus de
temps que de formatter ce qu'on va ecrire.
Donc les differences de performances entres les 2 methodes doivent êtres
minimes.
Par contre entre un sprintf et un << dans un stringstream les
differences de performances sont plus flagrantes (en faveur du sprintf).

Reste à voir si le gain en performance vaut vraiment le coup par
rapport au gain en facilité (et donc en temps) de codage.

A mon avis dans 99% des cas c'est non.

JBB

Avatar
kanze
Pierre Maurette wrote:

En conclusion, je te conseille fortement de bannir le printf
ainsi que les char * d'ailleurs qui sont des reliques du C.


Tout celà me semble frappé au coin du bon sens. Je me permets
une question supplémentaire : quelqu'un qui ajourd'hui apprend
C++ et qui resterait dans une optique de code neuf (voeux
pieux) peut-il faire l'économie de l'apprentissage de printf()
et consorts ?


Tout à fait. Au moins qu'il veut se servir de boost::format ou
Gabi::Format.

En particulier pour son avatar sprintf(), cette fonction et sa
chaîne de format reste-t-elle indispensable ?


Je dirais que sprintf est encore pire que les autres. À tel
point qu'elle est dépréciée même en C. Selon le cas, on a
ostringstream ou ostrstream.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
kanze
JBB wrote:

J'aurais une question très simple. Quel est e plus rapide
entre un affichage avec cout ou avec printf. En lisant
l'ouvrage "La qualité en C++" de Philippe Prados j'ai
l'impression que l'utilisation de cout devrait donner un
résultat plus rapide car optimisé. Néanmoins, certaines
lectures faites sur le Net indique que printf est plus
rapide.

Qui croire ?


Dernière remarque:

lors d'un cout ou d'un printf le fait d'ecrire reellement sur
la console (ou dans un fichier avec printf ou ofstream << )
prend beaucoup plus de temps que de formatter ce qu'on va
ecrire.


Ça dépend. Une bonne conversion flottante n'est pas triviale.
Les deux sont bufferisés par défaut ; on n'appelle le SE que
quand le buffer est plein. Et au moins Unix, lui, ne fait que
copier le buffer en mémoire interne au système, sans pour autant
l'écrire physiquement où que ce soit, avant de retourner.

Donc les differences de performances entres les 2 methodes
doivent êtres minimes. Par contre entre un sprintf et un <<
dans un stringstream les differences de performances sont plus
flagrantes (en faveur du sprintf).


Parce qu'il ne font pas la même chose. Dans le temps, je
connaissais des implémentations de printf qui était très vite
aussi. Les résultats n'étaient pas forcément corrects, mais qui
s'occupe d'un petit détail comme ça.

Reste à voir si le gain en performance vaut vraiment le coup
par rapport au gain en facilité (et donc en temps) de codage.


Dans le cas des sorties vers une chaîne, tout dépend de ce que
tu veux faire. S'il te faut une chaîne, rien ne dit que
ostringstream soit moins rapide que de formatter dans un char[],
puis en construire la chaîne. Et si tu as besoin de mettre la
chaîne générée dans un buffer précis, c'est pour ça qu'il y a
ostrstream.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
Fabien LE LEZ
On 4 Jul 2005 08:01:55 -0700, :

S'il te faut une chaîne, rien ne dit que
ostringstream soit moins rapide que de formatter dans un char[],


... et de toutes façons, toutes les considérations métaphysiques ne
mènent pas bien loin. Le mieux c'est de mesurer le temps que prend le
code considéré en utilisant les iostream, s'apercevoir que c'est
tellement rapide que ça ne vaut pas le coup de chercher à optimiser,
et passer à autre chose. :-)

Avatar
James Kanze
Fabien LE LEZ wrote:
On 4 Jul 2005 08:01:55 -0700, :


S'il te faut une chaîne, rien ne dit que ostringstream soit
moins rapide que de formatter dans un char[],



... et de toutes façons, toutes les considérations
métaphysiques ne mènent pas bien loin. Le mieux c'est de
mesurer le temps que prend le code considéré en utilisant les
iostream, s'apercevoir que c'est tellement rapide que ça ne
vaut pas le coup de chercher à optimiser, et passer à autre
chose. :-)


Ce qui est sans doute la remarque la plus sage de ce thread (y
compris les miens).

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34


1 2