PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > fr.comp.lang.c++ > performance de lecture de fichiers formatés
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
performance de lecture de fichiers formatés

Réponse
 
LinkBack Outils de la discussion
Vieux 04/05/2008, 16h33   #17
Marc Espie
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: performance de lecture de fichiers formatés

In article <481dd692$0$933$ba4acef3@news.orange.fr>,
Sylvain SF <sylvain@boiteaspam.info> wrote:
>Fabien LE LEZ wrote on 04/05/2008 17:08:
>> On Sun, 04 May 2008 11:14:49 +0200, Ploc <ploc@clop.invalid>:
>>
>>> char *lc=(char*)malloc(100 * sizeof(lc));
>>> [...]
>>> fscanf(f, "%s %g %g %g", lc, &x, &y, &z);

>>
>> Comme indiqué précédemment, si jamais la longueur de la chaîne
>> "labelXXX" est supérieure à 100, boum !

>
>fscanf_s(f, "%s %g %g %g", lc, 100, &x, &y, &z);
>
>est supporté par gcc, non ?


Non.

gcc est un compilateur.

La bibliotheque standard (et ses extensions) n'en font pas partie.
  Réponse avec citation
Vieux 04/05/2008, 16h40   #18
Fabien LE LEZ
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: performance de lecture de fichiers formatés

On Sun, 04 May 2008 17:30:31 +0200, "Sylvain SF"
<sylvain@boiteaspam.info>:

>est supporté par gcc, non ?


Mais du coup, ce n'est plus du C. Et si j'ai bien saisi, l'OP a besoin
de la portabilité.
(Par ailleurs, même si on accepte ce code, il faudra refaire le test
de performance.)

  Réponse avec citation
Vieux 04/05/2008, 16h45   #19
Fabien LE LEZ
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: performance de lecture de fichiers formatés

On Sun, 04 May 2008 11:14:43 +0200, Ploc <ploc@clop.invalid>:

>Le bout de code que j'ai écrit est juste là pour des questions de test
>que j'ai codé pour essayer d'expliquer les différences de rapidité entre
>deux versions d'un programme réel. Mais la, ca n'a plus grand chose à
>voir avec l'existant.


Ben justement, le code en C et le code en C++ ne font pas la même
chose. Difficile donc de les comparer.

>Ce n'est pas très génant pour nous de garder le code existant en C.


Si le code existant fonctionne bien (ce qui n'est pas le cas du code C
que tu as fourni ici), effectivement, le changer ne sert pas à
grand-chose.

  Réponse avec citation
Vieux 04/05/2008, 16h56   #20
Fabien LE LEZ
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: performance de lecture de fichiers formatés

>Après quelques essais, j'ai bien l'impression que parser soi-même les
>données apporte un gain de performances assez confortable.


Ça se confirme. Et je me suis aperçu que mmap() ne change pas
grand-chose.

Le code que j'avais proposé, avec une fonction main() plus standard
(cf ci-dessous), donne d'aussi bons résultats.

Manifestement, au moins dans gcc, scanf est effroyablement lent, et >>
encore plus.

Seule autre modification : dans la série "cachez ce char const* que je
ne saurais voir", j'ai uniformisé pour n'utiliser que std::string,
même dans Source.

Voici donc un programme en C++ standard, certes un peu long, mais qui
est très largement plus rapide que ton code en C (et, a fortiori, que
ton code en C++).



#include <string>

class Source
{
public:
typedef std::string::const_iterator const_iterator;
bool Fini() const { return ptr == Fin(); }
void Avancer() { ++ptr; }
char Get() const { return *ptr; }
const_iterator Ptr() const { return ptr; }
const_iterator Fin() const { return src.end(); }

Source (std::string const& src_) : src (src_), ptr (src_.begin())
{}

private:
std::string const& src;
const_iterator ptr;
};

struct Destination
{
std::string label;
float a, b, c;
};

void RechercheDebutLigne (Source& src)
{
bool fin_ligne_trouvee= false;
while (!src.Fini())
{
if (src.Get()=='\n')
{
fin_ligne_trouvee= true;
}
else if (fin_ligne_trouvee)
{
return;
}
src.Avancer();
}
}

bool Lire (float& dest, Source& src)
{
dest= 0;
bool negatif= false;
float decimale= 0.1;
bool info_rencontree= false;
bool virgule_rencontree= false;

while (!src.Fini())
{
if (src.Get() == '\n')
{
break;
}

if (src.Get() == '-')
{
if (info_rencontree)
{
return false; // mal formé
}
negatif= true;
}
else if (src.Get() == '.')
{
if (virgule_rencontree)
{
return false; // mal formé
}
virgule_rencontree= true;
info_rencontree= true;
}
else if (src.Get() >= '0' && src.Get() <= '9')
{
if (virgule_rencontree)
{
dest+= decimale * (src.Get()-'0');
decimale /= 10;
}
else
{
dest*= 10;
dest+= src.Get()-'0';
}
info_rencontree= true;
}
else if (info_rencontree)
{
break;
}
src.Avancer();
}

if (negatif)
{
dest= -dest;
}
return info_rencontree;
}

bool Lire (std::string& dest, Source& src)
{
Source::const_iterator debut= src.Fin();

while (!src.Fini())
{
if (src.Get() == '\n')
{
break;
}

if (src.Get() == ' ' || src.Get() == '\t')
{
if (debut != src.Fin())
{
break;
}
}
else if (debut == src.Fin())
{
debut= src.Ptr();
}
src.Avancer();
}

if (debut == src.Fin())
{
return false;
}
else
{
dest.assign (debut, src.Ptr());
return true;
}
}


bool Lire (Destination& dest, Source& src)
{
bool ok= Lire (dest.label, src)
&& Lire (dest.a, src)
&& Lire (dest.b, src)
&& Lire (dest.c, src);
RechercheDebutLigne (src);
return ok;
}





#include <iostream>
#include <fstream>

int main()
{
using namespace std;
char const nom_src[]= "data.txt";
ifstream ifs (nom_src);

string ligne;
unsigned int num_ligne= 0;
while (std::getline (ifs, ligne, '\n'))
{
++num_ligne;
Destination d;
Source s (ligne);
if (!Lire (d, s))
{
// erreur
}
}
cerr << num_ligne << " lignes lues" << endl;
}

  Réponse avec citation
Vieux 04/05/2008, 17h54   #21
Sylvain SF
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: performance de lecture de fichiers formatés

Fabien LE LEZ wrote on 04/05/2008 17:40:
>
>> [fscanf_s] est supporté par gcc, non ?

>
> Mais du coup, ce n'est plus du C.


qui, quoi ?

> Et si j'ai bien saisi, l'OP a besoin de la portabilité.


ces _s sont supportés par VC 14+ (second compilo listé par le PO)
de nombreux posts (web) sur le net laissaient penser que gcc
(et ses libraries usuelles !...) les supportaient aussi.

> si on accepte ce code, il faudra refaire le test de performance.


dans l'absolu oui, je commentais seulement le rique de BO.
(ça n'impliquait pas que ce serait a priori moins ou plus rapide).

Sylvain.
  Réponse avec citation
Vieux 04/05/2008, 18h18   #22
Ploc
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: performance de lecture de fichiers formatés

Fabien LE LEZ wrote:
> On Sat, 03 May 2008 21:46:32 +0200, Ploc <ploc@clop.invalid>:
>
>> En passant de C (à base de fscanf) à c++ avec ifstream (voir le code en
>> bas), je passe de 1min 40s en C à 3min 10s en c++.

>
> Après quelques essais, j'ai bien l'impression que parser soi-même les
> données apporte un gain de performances assez confortable.
>
> Soit donc un
>
> struct Destination
> {
> std::string label;
> float a, b, c;
> };
>
> que je remplis par lecture d'une ligne dans le fichier, puis que je
> jette sans rien en faire. Recommencer jusqu'à épuisement du fichier.
> En cas d'erreur de format, on considère que la ligne est déficiente,
> et on passe à la suivante.
>
> J'ai fait les tests sur un AMD Athlon64 double coeur, 2,4 GHz, avec
> 2 Go de RAM. Debian 64 bits, g++ 4.1.2, optimisation "-O3".
>
> Commençons par un fichier de 953 Mo.
> real 0m24.446s
> user 0m11.129s
> sys 0m0.412s
>
> 953.674 Mo une deuxième fois :
> real 0m13.218s
> user 0m11.277s
> sys 0m0.372s
>
> La deuxième fois, le fichier était déjà en cache, ce qui semble
> confirmer que la ligne "user" représente bien le temps que le
> processeur met à convertir les données.
>
> Un fichier un peu plus gros (3814 Mo) confirme une vitesse de
> traitement d'environ 85 Mo/s :
> real 2m34.111s
> user 0m45.239s
> sys 0m3.844s
>
> Si maintenant je mets en commentaire la ligne 134 (i.e. je supprime
> l'appel à std::string::assign()), j'obtiens, pour mon fichier de
> 3814 Mo :
>
> real 2m5.296s
> user 0m17.713s
> sys 0m3.844s
>
> soit 2,5 fois moins. La recopie de la chaîne de caractères "labelXXX"
> est donc, de loin, ce qui prend le plus de temps.
>
> C'est bon à savoir : si jamais tu n'as besoin de ce texte que de temps
> en temps, tu peux te contenter de conserver les pointeurs sur le début
> et la fin de la chaîne (la fonction mmap() garantit que la mémoire
> pointée sera toujours accessible). Et si ce texte est juste là pour
> faire joli, et ne sert à rien, tu peux carrément ne pas conserver sa
> valeur.
>
>
>
>
> < snip code de test >
>
>



J'ai finalement pu tester ce programme.
Tel quel il est assez proche en durée de la version c.
En sortant la ligne 'Destination d' de la boucle, on fait même mieux (on
teste toujours le temps d'I/O, pour l'utilisation des valeurs extraites,
on verra plus tard).
Par contre, le mmap passera jamais sous visual studio.

La remarque sur l'extraction des labels est très interressante.
Malheureusement, j'en ai besion assez vite. Dommage.


  Réponse avec citation
Vieux 04/05/2008, 18h21   #23
Fabien LE LEZ
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: performance de lecture de fichiers formatés

On Sun, 04 May 2008 19:18:40 +0200, Ploc <ploc@clop.invalid>:

>Tel quel il est assez proche en durée de la version c.


Bizarre. J'ai une différence d'un facteur 4 ou 5.
(Sauf en l'absence d'optimisation ("-Ox"))

>Par contre, le mmap passera jamais sous visual studio.


Il y a l'équivalent presque exact sous Windows.
De toute façon je t'ai donné une autre version, en C++ standard.

  Réponse avec citation
Vieux 04/05/2008, 18h22   #24
Fabien LE LEZ
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: performance de lecture de fichiers formatés

On Sun, 04 May 2008 19:18:40 +0200, Ploc <ploc@clop.invalid>:

>La remarque sur l'extraction des labels est très interressante.


Qu'est-ce que tu dois en faire exactement, de ces labels ?
  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 12h36.


Édité par : vBulletin® version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,22094 seconds with 16 queries