renyone
Messages postés71Date d'inscriptionvendredi 9 mars 2007StatutMembreDernière intervention12 avril 2010
-
21 août 2008 à 14:48
renyone
Messages postés71Date d'inscriptionvendredi 9 mars 2007StatutMembreDernière intervention12 avril 2010
-
25 août 2008 à 10:00
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...
olibara
Messages postés666Date d'inscriptiondimanche 16 décembre 2007StatutMembreDernière intervention11 mars 20106 22 août 2008 à 18:01
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 !
krishou
Messages postés60Date d'inscriptiondimanche 9 janvier 2005StatutMembreDernière intervention21 août 20081 21 août 2008 à 16:18
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 ...;)
xmox667
Messages postés357Date d'inscriptionjeudi 8 juin 2006StatutMembreDernière intervention26 décembre 20114 21 août 2008 à 21:14
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+
renyone
Messages postés71Date d'inscriptionvendredi 9 mars 2007StatutMembreDernière intervention12 avril 20103 22 août 2008 à 13:38
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... :)
olibara
Messages postés666Date d'inscriptiondimanche 16 décembre 2007StatutMembreDernière intervention11 mars 20106 22 août 2008 à 14:45
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
renyone
Messages postés71Date d'inscriptionvendredi 9 mars 2007StatutMembreDernière intervention12 avril 20103 22 août 2008 à 15:00
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.
olibara
Messages postés666Date d'inscriptiondimanche 16 décembre 2007StatutMembreDernière intervention11 mars 20106 22 août 2008 à 15:08
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
renyone
Messages postés71Date d'inscriptionvendredi 9 mars 2007StatutMembreDernière intervention12 avril 20103 22 août 2008 à 15:33
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...
:'(