Vitesse d'execution de code STL sous VisualC++ !?!?

Vitesse d'execution de code STL sous VisualC++ !?!? - C++ - Programmation

Marsh Posté le 28-11-2002 à 15:44:29    

Salut à tous!
 
Voici un petit programme (ne pas se préoccuper des controles d'erreurs et de l'utilité du code, ce n'est pas le but).
Sachant la manière dont tout bon compilateur C++ traite les instructions de streaming C++, et la manière dont le formattage de chaine est traité avec les fonctions C standard, à votre avis, quel devrait être la parti de code la plus rapide:
 

Code :
  1. #include <Windows.h>
  2. #include <fstream>
  3. #include <iostream>
  4. using namespace std;
  5. static int iMax = 50000;
  6. int main(int argc, char* argv[])
  7. {
  8. int  i;
  9. int  i1=1,i2=2,i3=3,i4=4,i5=5;
  10. char szString[] = "<VALUE>";
  11. DWORD dwStart = GetTickCount();
  12. #if 0
  13. FILE *pFile = fopen("C:\\test_ctype.txt","wt" );
  14. for(i=0;i<iMax;i++)
  15. {
  16.  fprintf(pFile,"This is the dummy string number: %d\n",i);
  17.  fprintf(pFile,"i+i=%d    i/2=%g    %s\n",i+i,double(i)/2.0,szString);
  18.  fprintf(pFile,"Value1=%d Value2=%d Value3=%d Value4=%d Value5=%d\n",i1,i2,i3,i4,i5);
  19. }
  20. fflush(pFile);
  21. fclose(pFile);
  22. #else
  23. ofstream out("C:\\test_cpptype.txt",ios_base::out ); // Write
  24. for(i=0;i<iMax;i++)
  25. {
  26.  out << "This is the dummy string number: " << i << endl;
  27.  out << "i+i=" << i+i << "    i/2=" << double(i)/2.0 << "    " << szString << endl;
  28.  out << "Value1=" << i1 << " Value2=" << i2 << " Value3=" << i3 << " Value4=" << i4 << " Value5=" << i5 << endl;
  29. }
  30. out << flush;
  31. #endif
  32. DWORD dwStop = GetTickCount();
  33. cout << "Time = " << dwStop - dwStart << endl;
  34. return 0;
  35. }


 
Je precise que les tests on été fait en mode release, avec "Maximize Speed" dans les settings du project.
 
Et bien avec Visual, le plus rapide c'est avec des fprintf... :heink:  
(Lancement de l'application une vingtaine de fois dans les 2 mode, avec le #if 1 ou #if 0 , et moyenne effectuée)
La différence va du simple au double (en moyenne, 2fois plus vite avec les fprintf!!!  :pt1cable:  :(  :??:  :heink: )
 
Alors 2 choses l'une:
1) Ou bien je n'ai rien compris à la lib iostream  :pt1cable:  
2) Ou bien l'implementation de STL par Microsoft est délibéremment baclée, voir ralentie...  :fou: (sachant le support desastreux des templates par le compilo de Visual, ça ne m'etonnerait pas...)


Message édité par YungMakko le 28-11-2002 à 16:45:45

---------------
In tartiflette, we trust!
Reply

Marsh Posté le 28-11-2002 à 15:44:29   

Reply

Marsh Posté le 28-11-2002 à 16:34:26    

quand tu compiles en mode DEBUG, chaque appel de routine est alourdi par des routines de protection & co...
 
dans le cas du printf, autant en DEBUG qu'en release, le code de printf utilisé est le même.
 
dans le cas des iostreams, en DEBUG c'est extrêment ralenti par rapport au release...
 
as-tu comparé en DEBUG ou en RELEASE ?

Reply

Marsh Posté le 28-11-2002 à 16:35:47    

et effectivement je suis d'accord avec toi, la vitesse des iostream en debug sont une horreur....

Reply

Marsh Posté le 28-11-2002 à 16:37:51    

bjone a écrit a écrit :

et effectivement je suis d'accord avec toi, la vitesse des iostream en debug sont une horreur....




 
Humm, oui le problème est que ce project est compilé en release avec optimisation maximum... c'est sur le debug n'est pas fait pour faire ce genre de test.
 
J'ai éditer le 1er message pour le préciser.


Message édité par YungMakko le 28-11-2002 à 16:39:29

---------------
In tartiflette, we trust!
Reply

Marsh Posté le 28-11-2002 à 16:46:26    

ca vient de deux chose:
 

  • dans la version C, chaque boucle declenche 3 ecritures (3 fprintf alors que je compte 20 << dans la version C++.

si tu mets un printf par données, ca devrait aller nettement moins vite

  • l'equivalence C++ de '\n' c'est '\n' et pas endl qui est en fait un '\n'+flush


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 28-11-2002 à 16:54:47    

oki, sympa pour le endl, je savais pas qu'il flushait tout seul ;)

Reply

Marsh Posté le 28-11-2002 à 17:06:50    

Taz@PPC a écrit a écrit :

ca vient de deux chose:
 

  • dans la version C, chaque boucle declenche 3 ecritures (3 fprintf alors que je compte 20 << dans la version C++.

si tu mets un printf par données, ca devrait aller nettement moins vite

  • l'equivalence C++ de '\n' c'est '\n' et pas endl qui est en fait un '\n'+flush






 
J'avais lu que que les streams etaient plus rapide que les fprintf du fait que dans le fprintf la chaine de caractère est interprété au runtime, alors que ce n'est pas le cas pour les streams. Je n'avais pas pensé au fait que chaque << prenait du tout vu que, en effet, ce sont des opérateurs, donc equivalent à un appel de fonction si ils ne sont pas inline.
Il doit y a voir certain cas ou tu gagnes quand même un peu.  
 
Si tu as du code de ce style qui doit être optimisé à mort, tu utiliserai quelle technique pour ecrire dans un fichier (pas d'assembleur, le code doit être multi-plateforme) ?
 
Merci beaucoup en tout cas pour cet eclairage très lumineux!!! :)
Faut vraiment que je mette aux STL! Voilà le gros problème d'être soit disans un spécialiste des techno Microsoft et patati et patata... c'est que t'oublie d'être un pro dans les technos de bases, parceque tu les utilises jamais! Je vais vraiment devoir remedier à ces lacunes inacceptables!  :D


Message édité par YungMakko le 28-11-2002 à 17:07:19

---------------
In tartiflette, we trust!
Reply

Marsh Posté le 28-11-2002 à 17:10:43    

je bufferiserais avec des ostringstream, par exemple.


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 28-11-2002 à 17:14:38    

Taz@PPC a écrit a écrit :

je bufferiserais avec des ostringstream, par exemple.




 
J'vais regarder ça! Si je trouve une version qui va vraiment plus vite que les fprintf, je la posterai ici comme example...
 
Merci beaucoup!  :)


---------------
In tartiflette, we trust!
Reply

Marsh Posté le 28-11-2002 à 17:18:34    

garde surtout a l'esprit que l'avantage du C++ ce sont aussi des E/S simplifiées


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 28-11-2002 à 17:18:34   

Reply

Marsh Posté le 28-11-2002 à 17:27:02    

Taz@PPC a écrit a écrit :

garde surtout a l'esprit que l'avantage du C++ ce sont aussi des E/S simplifiées




 
Oui tout à fait, mais dans ce que je recherche pour un cas précis, c'est la performance maximale avant tout et que le code soit portable, peu importe si l'approche n'est pas vraiment OO et si le source est plus complexe. En général, j'utilise la sérialization (surtout en MFC) pour stocker le contenu de mes objects... mais question perf, c'est pas ça; mais comme ce n'était pas critique jusqu'à maintenant...
 
Remarque, la serialization, même à la sauce MFC, ce n'est rien d'autre que de définir des operateur << et >> pour tes objects... j'aurai du m'en douter un peu.


Message édité par YungMakko le 28-11-2002 à 17:29:18

---------------
In tartiflette, we trust!
Reply

Marsh Posté le 29-11-2002 à 04:53:20    

Désactiver la gestion d'exception n'a rien changé, ce qui m'étonnes...
A mon avis, la STL bought-by-Microsoft ne casse pas des briques.
 
Ce serait bien d'avoir le test de quelqu'un disposant de la YASLI (Yet Another Standard Library Implementation).
(C'est la meilleure en fait)


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 29-11-2002 à 08:26:48    

Musaran a écrit a écrit :

Désactiver la gestion d'exception n'a rien changé, ce qui m'étonnes...
A mon avis, la STL bought-by-Microsoft ne casse pas des briques.
 
Ce serait bien d'avoir le test de quelqu'un disposant de la YASLI (Yet Another Standard Library Implementation).
(C'est la meilleure en fait)




 
ou la SGI


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 29-11-2002 à 13:12:54    

Musaran a écrit a écrit :

A mon avis, la STL bought-by-Microsoft ne casse pas des briques.




 
A mon avis aussi. D'ailleurs il me semble que les "fstream" sont basés sur des FILE* chez MS.
Et en général j'ai lu que les perfs des "ostream" font pas top en général (c'est de la faute des implémentations) alors qu'en théorie ca devrait être plus rapide.

Reply

Marsh Posté le 30-11-2002 à 10:56:24    

kenshiro182 a écrit a écrit :

 
 
A mon avis aussi. D'ailleurs il me semble que les "fstream" sont basés sur des FILE* chez MS.
Et en général j'ai lu que les perfs des "ostream" font pas top en général (c'est de la faute des implémentations) alors qu'en théorie ca devrait être plus rapide.




 
ben ouais. apparemment MS a implémenté les stream comme des surcourches ou E/S du C ... alors ca peche.


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 30-11-2002 à 12:04:39    

Musaran a écrit a écrit :

 
A mon avis, la STL bought-by-Microsoft ne casse pas des briques.




 
et je crois que c'est un avis quasiment unanimement partagé par tous...

Reply

Marsh Posté le 30-11-2002 à 12:09:44    

fprintf est sans doute plus rapide mais il n'est pas type safe.
 
si tu pars dans la performance, il faut savoir qu'il vaut toujours mieux ecrire un gros bloc d'un coup, plutot que plusieurs petits blocs et de regrouper les appels d'ecriture plutot que de les disperser dans des tas de petites fonctions.
Ce qui est un objectif qui contrarie un peu la conception objet.
 
A mon avis la lecture/ecriture la plus rapide, c'est la lecture ecriture asynchrone mais ca n'est pas disponible a ton niveau d'abstractions. De meme l'utilisation des fichiers mappes est surement preferable pour des lectures aleatoires.
 
Le fichier d'entree sortie a la C/C++ n'a pas ete pense pour les performances mais pour la standardisation du code, et celui du C++ a apporte une plus grande extensibilite et une type safety nouvelle, ce qui se traduit dans cette implantation par une perte de performance.
 
Avant de passer des jours a optimiser tes entrees-sorties demande toi aussi si cela en vaut la peine et si cela te posera probleme a ton utilisateur. Et si le surcout apporte par la maintenance de ton code sera compensee parl'augmentation des performances.
 
LeGreg


---------------
voxel terrain render engine | animation mentor
Reply

Marsh Posté le 30-11-2002 à 12:14:24    

legreg a écrit a écrit :

fprintf est sans doute plus rapide mais il n'est pas type safe.
 
si tu pars dans la performance, il faut savoir qu'il vaut toujours mieux ecrire un gros bloc d'un coup, plutot que plusieurs petits blocs et de regrouper les appels d'ecriture plutot que de les disperser dans des tas de petites fonctions.
Ce qui est un objectif qui contrarie un peu la conception objet.
 
A mon avis la lecture/ecriture la plus rapide, c'est la lecture ecriture asynchrone mais ca n'est pas disponible a ton niveau d'abstractions. De meme l'utilisation des fichiers mappes est surement preferable pour des lectures aleatoires.
 
Le fichier d'entree sortie a la C/C++ n'a pas ete pense pour les performances mais pour la standardisation du code, et celui du C++ a apporte une plus grande extensibilite et une type safety nouvelle, ce qui se traduit dans cette implantation par une perte de performance.
 
Avant de passer des jours a optimiser tes entrees-sorties demande toi aussi si cela en vaut la peine et si cela te posera probleme a ton utilisateur. Et si le surcout apporte par la maintenance de ton code sera compensee parl'augmentation des performances.
 
LeGreg




+1  :sol:


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 01-12-2002 à 02:44:14    

En C++ il y a souvent moyen d'avoir une conception gagnante sur tout les tableaux: plus performante, plus sûre, plus simple d'emploi, plus compacte.
 
L'inline résoud le problème de la segmentation en petite fonctions.
Un cache/buffer transparent adoucit les E/S segmentées.
 
Et il me reste bien d'autres choses à apprendre.
 
J'ai utilisé le mappage en mémoire une fois. Ça pulvérise tout le reste, et de loin.


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 01-12-2002 à 11:33:53    

Musaran a écrit a écrit :

J'ai utilisé le mappage en mémoire une fois. Ça pulvérise tout le reste, et de loin.




 
vive mmap!


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 02-12-2002 à 00:42:59    

Non, c'était sous Fenêtres, et il faut une belle série d'APIs.
C'est bête, j'ai perdu le code.
 
Existe t'il une librairie multi-plateforme pour le mappage ?


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 02-12-2002 à 07:03:38    

aucune idée


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 02-12-2002 à 10:07:57    

Musaran a écrit a écrit :

Non, c'était sous Fenêtres, et il faut une belle série d'APIs.
C'est bête, j'ai perdu le code.
 
Existe t'il une librairie multi-plateforme pour le mappage ?




 
ça utilise des fonctionalités bien spécifiques du Kernel de Windows, et je ne sais pas si il y a des implémentations digne de ce nom sur d'autres système. Et si il y en a, apportent t'elles autant de performances?
 
Sinon j'ai le code dans un bouquin, j'avais fais des essais avec, ça t'intésse?


Message édité par YungMakko le 02-12-2002 à 10:08:16

---------------
In tartiflette, we trust!
Reply

Marsh Posté le 02-12-2002 à 12:35:20    

YungMakko a écrit a écrit :

 
ça utilise des fonctionalités bien spécifiques du Kernel de Windows, et je ne sais pas si il y a des implémentations digne de ce nom sur d'autres système. Et si il y en a, apportent t'elles autant de performances?




 
Ben sous Unix il y a mmap...

Reply

Marsh Posté le 02-12-2002 à 12:41:05    

Nickel alors!  :D


---------------
In tartiflette, we trust!
Reply

Marsh Posté le 03-12-2002 à 03:19:35    

YungMakko a écrit a écrit :

Sinon j'ai le code dans un bouquin, j'avais fais des essais avec, ça t'intésse?


Pas la peine, je sais que j'ai le code sur une feuille de mes cours.
 
Dans une pile de 20 Kg de papier :sweat: .


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed