Et c'est une catastrophe...fork de la discussion Choisir entre programmation générique et programmation OO
Vous permettez que je rage un peu sur IOStream ? Cette partie du C++ m'irrite systématiquement à chaque fois que je veux l'utiliser.
<RAGE>
Je suis tombé récemment sur un post sur stack overflow qui résume bien la situation :
Amen.Q : C++0X Concepts are gone. Which other features should go too?
A:
Of course, plenty of old C cruft could be ditched too, but recently, I've discovered that the one change I'd really love to see is...... ditching the Iostreams library. Toss it out, and build a new STL-style I/O library based on generic programming.
The current OOP-styled Iostreams library is ugly, slow, overcomplicated and inflexible. There's too much voodoo involved in defining new streams, too few standard stream types involved, too little flexibility (the problem that made me realize how limited the library is, was that I needed to extract a float from a string. Easy to do with stringstream, but if you need to do it often, you don't want to have to copy the input string every time (as the stringstream does) -- where's the stream that works on an existing iterator range? Or a raw array, even?)
Throw IOstreams out, develop a modern replacement, and C++ will be vastly improved.
Je ne sais pas si vous avez déjà lu cette série de post déprimante par Raymond Chen (guru mircrosoft C/C++) et Rico Mariani (guru microsoft C#) ?
Elle commence par Raymond Chen qui écrit une petite appli C++ assez simple - un dictionnaire chinois/anglais. Rico Mariani décide alors de réécrire cette appli ligne par ligne en C#. Et Les perfs de l'appli C# enfonce celle de l'appli C++ dans les grandes largeurs !! (x10 !). Quelques jours plus tard et plusieurs update plus tard, l'appli C++ de Raymond Chen finit par rattraper les perfs du C# mais il a du se taper de nombreuses passes d'optimisation et écrire du code bas-niveau de plus en plus horrible et de plus en plus long.
Et pourquoi l'appli C++ originale donne des perfs aussi mer.... ?
IOstream
L'horreur est la suivante : Pour peupler le dictionnaire, il faut ouvrir un fichier texte encodé au format 950 (du chinois) et le lire ligne par ligne tout en convertissant chaque ligne en Unicode.
Le code C++ :
Le code C# :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 std::wifstream src; src.imbue(std::locale(".950")); src.open("cedict.b5"); wstring s; while (getline(src, s)) { // do something }
Et bien c'est une boucherie.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 StreamReader src = new StreamReader( "cedict.b5", System.Text.Encoding.GetEncoding(950)); string s; while ((s = src.ReadLine()) != null) { // do something }![]()
Ce code C# est x20 plus rapide chez moi. (VS2008)
J'ai essayé d'analyser ce que fait respectivement chaque code et si je ne me suis pas trompé :
Le code C# mappe le fichier en mémoire puis le parcours ligne par ligne, tout en convertissant chaque ligne en Unicode en appelant MultiByteToWideChar() sur la ligne entière.
Le code C++ ouvre un flux, puis parcours le flux ligne par ligne et appelle pour chaque caractère la fonction de conversion vers l'Unicode codecvt::do_in, qui est bien évidement une fonction virtuelle qui ne s'inline pas, qui lock un mutex pour le fun, tout ça pour finalement appeler MultiByteToWideChar.... sur un seul caractère à la fois.
</RAGE>
Partager