Lecture rapide d'un fichier volumineux [Résolu]

Signaler
Messages postés
71
Date d'inscription
vendredi 9 mars 2007
Statut
Membre
Dernière intervention
12 avril 2010
-
Messages postés
71
Date d'inscription
vendredi 9 mars 2007
Statut
Membre
Dernière intervention
12 avril 2010
-
Bonjour.

Je vous expliquer mon problème: je veux lire un fichier (txt ou csv) qui fait 3 Go, parser chaque ligne et creer des objets en fontion des données que j'ai récupérées sur chaque ligne. Le problème est que c est super lent. Quand je regarde l'utilisation du processeur, je varie entre 0 et 4%. Mon fichier possede qd meme 14 millions de lignes...
Le problème vient-til de la lecture du fichier ?
Acutellement j utilise un Streamreader sr et pour chaque ligne je crée un string line = sr.ReadLine(). Puis je splitte ma line et je crée mes objets...

Merci d'avance pour vos réponse!

21 réponses

Messages postés
666
Date d'inscription
dimanche 16 décembre 2007
Statut
Membre
Dernière intervention
11 mars 2010
4
Donc le probleme ne viens pas de la lecture de ton gros fichier
Mais de l'insertion d'un grand nombre d'enregistrement indexé dans ton Btree

Ce qui ne m'etonne pas du tout !!

Tu dois donc jouer sur
- clef d'indexation
- L'information que tu stoque
- Le format de stockage

A ce niveau la ca devient le "vrai" metier de l'informaticien : etudier la solution la plus fonctionelle et la plus viable et contourner les multiples obstacles du monde reel !
Messages postés
71
Date d'inscription
vendredi 9 mars 2007
Statut
Membre
Dernière intervention
12 avril 2010
3
Personne n'a une idée ?
^^
Messages postés
60
Date d'inscription
dimanche 9 janvier 2005
Statut
Membre
Dernière intervention
21 août 2008

Une mini optimisation qui ne changera probablement pas grand chose mais pourquoi créer un string a chaque boucle, pourquoi ne pas juste l'écraser ...;)
Messages postés
71
Date d'inscription
vendredi 9 mars 2007
Statut
Membre
Dernière intervention
12 avril 2010
3
En fait, je comprends pas pourquoi mon UC ne monte qu'à 4% surtout...
Messages postés
666
Date d'inscription
dimanche 16 décembre 2007
Statut
Membre
Dernière intervention
11 mars 2010
4
Tu peux montrer ta boucle de lecture ?
Messages postés
357
Date d'inscription
jeudi 8 juin 2006
Statut
Membre
Dernière intervention
26 décembre 2011
3
Salut,
C'est un très gros fichier (pour un fichier txt) et les accès aux disque dur sont très lent.
Est ce tu as d'autres applications qui accèdent au disque en même temps que ton application?
Est ce que ton fichier est fragmenté?
A+
Messages postés
327
Date d'inscription
mardi 17 février 2004
Statut
Membre
Dernière intervention
10 avril 2010
7
Salut,

Si tu ne fais que lire le fichier, sans faire aucun traitement dessus, est ce que c'est toujours aussi lent, ou beaucoup moins?
Messages postés
666
Date d'inscription
dimanche 16 décembre 2007
Statut
Membre
Dernière intervention
11 mars 2010
4
tres bonne question !
Et regle fondamentale de debug
Chercher à isoler le traitement a problème !
Messages postés
666
Date d'inscription
dimanche 16 décembre 2007
Statut
Membre
Dernière intervention
11 mars 2010
4
Mais j'insiste un peu


Peux tu montrer le code de ta boucle de lecture ? Il y a souvent des trucs qu'on voit plus tellement on a l'habitude de les voir.


Sauf si c'est top secret bien sur !


 
Messages postés
71
Date d'inscription
vendredi 9 mars 2007
Statut
Membre
Dernière intervention
12 avril 2010
3
Salut à tous et merci pour votre réponse.
Je fais les différents tests et reviens vers vous d'ici peu!

Merci encore ;)
Messages postés
71
Date d'inscription
vendredi 9 mars 2007
Statut
Membre
Dernière intervention
12 avril 2010
3
Effectivement, quand je ne fais pas de traitement, c'est bien plus rapide et mon UC monte à 50%.
Le probleme vient d une méthode que j'utilise mais que je n'ai pas développé. J'utilise la méthode BTree.Put de l'api dotnet de Berkeley Db. Je ne sais pas si ça parle à quelqu'un... :)
Messages postés
327
Date d'inscription
mardi 17 février 2004
Statut
Membre
Dernière intervention
10 avril 2010
7
Ca mets combien de temps pour lire le fichier par curiosité? Chez moi je mets 40 sec pour lire un fichier de 1 GO
Messages postés
666
Date d'inscription
dimanche 16 décembre 2007
Statut
Membre
Dernière intervention
11 mars 2010
4
Salut les 40 secondes de WishhhMaster sont une norme correcte, tu peux osciller entre 20 a 60 secondes a mon avis sur une machine "normale"

Attention ce n'est vrai que si tu ne lis ou ecris q'UN seul fichier a la fois

A mon avis meme si ta boucle reste to secret et que tu ne veux pas en parler, ce qui se passe c'est c'est que ton Btree.Put fais des IO paralleles qui parasittent tout

Exemple

Tu lis sequentiellement 1 fichier de 2GB temps : +/- 30 seconde
Tu lis DEUX fichier de 2GB sur le meme disque en synchro acces l'un acces l'autre etc

Temps : peut etre 20 minutes !!
Messages postés
71
Date d'inscription
vendredi 9 mars 2007
Statut
Membre
Dernière intervention
12 avril 2010
3
Environ une minute pour 3 Go.
Messages postés
327
Date d'inscription
mardi 17 février 2004
Statut
Membre
Dernière intervention
10 avril 2010
7
Donc oui c'est définitivement le traitement :)
Désolé je ne connais pas Berkeley db.
Bonne chance =)
Messages postés
71
Date d'inscription
vendredi 9 mars 2007
Statut
Membre
Dernière intervention
12 avril 2010
3
Alors, non mon code n est pas du tout secret. En fait je lis dans mon fichier volumineux, je construis mes objets et je les serialize dans un autre fichier .db grace à la methode Put de la classe BTree de l'api DotNet de Berkeley Db.
Voici mon code :

while (line != null && line.Length > 0)
            {
                MarketDepth md = new MarketDepth();
               
                // DIVERS TRAITEMENT SUR LA LIGNE QUI NE CHANGE RIEN AU TEMPS D EXEC NI A L UTILISATION DU PROCESSEUR

                db.AddRecord(null, md);
                line = sr.ReadLine();
           
            }

Et AddRecord est sous cette forme:

public void AddRecord(Txn txn, MarketDepth value)
        {
            KeyForMarketDepth kfmd = new KeyForMarketDepth(value.Ric,
                                                           value.Date);
            DbEntry keyEntry  = _bdbFormatter.ToDbEntry<KeyForMarketDepth>(kfmd);
            DbEntry dataEntry = _bdbFormatter.ToDbEntry<MarketDepth>(value);
            WriteStatus status = _marketDepthDB.Put(txn, ref keyEntry, ref dataEntry, DbFile.WriteFlags.None);
           
        }

Si je commente la derniere ligne tout se passe bien. Par contre si je la laisse, l'utilisation de mon UC chute à 0-5% et la serialisation dans le fichier .db est super longue.

Merci encore
Messages postés
666
Date d'inscription
dimanche 16 décembre 2007
Statut
Membre
Dernière intervention
11 mars 2010
4
Salut

Tu veux donc dire que si tu ne fais PAS

            WriteStatus status = _marketDepthDB.Put(txn, ref keyEntry, ref dataEntry, DbFile.WriteFlags.None);

Tout va bien  ??

Donc d'apres moi et ce que j'ai dis un peu avant cela signifie que _marketDepthDB.Put fait des write su le dique qui bousculent tout

Ou se trouve cette DB ?
Peux tu essayer de mettre ton fichier a lire sur un AUTRE disque que celui de ta DB ?

Essaye, tu sera sans doute surpris !
Cela etant je supconne que _marketDepthDB.Put genere un Btree sur base d'une clef texte ce qui est aussi tres lent !! Mais comme ton CPU a l'air de bien se porter, essaye le coup du disque
Messages postés
71
Date d'inscription
vendredi 9 mars 2007
Statut
Membre
Dernière intervention
12 avril 2010
3
Bon j'ai changé mon fichier à lire de DD, ca n a rien changé. J'ai meme créé un objet à la main (sans lecture de fichier) et je l utilise à chaque fois dans AddRecord (je fais une boucle 1000000 fois) et toujours la meme chose...
:'(
Messages postés
666
Date d'inscription
dimanche 16 décembre 2007
Statut
Membre
Dernière intervention
11 mars 2010
4
Salut

Tu veux dire quoi ?
Quand tu cree un objet a la main et que tu l'ajoute 100000 fois dans ta DB ca vas tres vite ?
Messages postés
71
Date d'inscription
vendredi 9 mars 2007
Statut
Membre
Dernière intervention
12 avril 2010
3
Non non justement....