Split qui plante

Résolu
tibo76530 Messages postés 24 Date d'inscription mercredi 6 juin 2007 Statut Membre Dernière intervention 15 octobre 2008 - 5 mai 2008 à 14:43
tibo76530 Messages postés 24 Date d'inscription mercredi 6 juin 2007 Statut Membre Dernière intervention 15 octobre 2008 - 14 mai 2008 à 11:26
bonjour
je viens demander de l'aide car je planche sur un probleme de puis quelques jours, et je n'arrive pas à m'en sortir.
voila: je vais récupérer des données dans un fichier .txt. je récupère cela dans un streamreader que je lis ensuite ligne par ligne.
ensuite, je traite chaque ligne avec mon split afin de récupérer les différents champs contenus dedans.
mon problème est que le traitement est très lent, sans raison apparente. mon appli tombe en rade à partir de 2000 lignes à traiter, ce qui n'est vraiment ^pas beaucoup.
Si quelqu'un a une idée, je suis preneur. me demander si l'on veut mon code
tibo
PS: je ne savais pas dans quel rubrique poster, alors je l'ai mis la, du au Split dans le titre de la rubrique.

9 réponses

SharpMao Messages postés 1024 Date d'inscription mardi 4 février 2003 Statut Membre Dernière intervention 7 juin 2010 69
5 mai 2008 à 15:12
Hello,

Il faudra sans doute que tu mettes ton code,ou du moins, au moins la boucle qui fait le traitement, pour qu'on puisse t'aider. Difficile de faire mieux snas voir le code.

Amicalement, SharpMao

"C'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!"
(Coluche / 1944-1986 / Pensées et anecdotes)
3
SharpMao Messages postés 1024 Date d'inscription mardi 4 février 2003 Statut Membre Dernière intervention 7 juin 2010 69
6 mai 2008 à 08:32
Hello,
A mon avis, le problème ne vient ni du split, ni de la lecture du fichier.
J'ai essayer le bout de code que tu as mis, et avec un fichier de 100'000 lignes formatté comme suit :
1|2|3|4
2|4|6|8
3|6|9|12

Il me faut moins de 0.1 seconde pour exécuter ce code.
Si par contre, je rajoute
string s =""; //à l'extérieur du while
et
s+= temp[i] +" ";//dans la boucle for. Inutile de faire un .ToString, temp[i] est déjà un string.
et
s+= Environment.NewLine; // après la boucle for

Avec ça, le temps de traitement monte à presque 20 minutes !

Par contre, si j'utilise un StringBuilder (dans l'assembly System.Text)
StringBuilder sb =new StringBuilder();//à l'extérieur du while

s.AppendFormat("{0} ", temp[i]);//dans la boucle for
et
sb.AppendLine();// après la boucle for

Avec ça, le temps de traitement n'est plus que de 0.2 secondes !!

Mais attend, on peut faire encore mieux :
Si ton but est de récupérer tout le texte de ton fichier dans un string ou les '|' sont remplacés par des ' ', tu fais ça en une ligne :

string s = File.ReadAllText(nom).Replace('|', ' '
);

 Temps de rtaitement : inférieur à 0.05 secondes, toujours pour un fichier de 100'000 lignes !!!

Amicalement, SharpMao

"C'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!"
(Coluche / 1944-1986 / Pensées et anecdotes)
3
SharpMao Messages postés 1024 Date d'inscription mardi 4 février 2003 Statut Membre Dernière intervention 7 juin 2010 69
6 mai 2008 à 08:36
Encore une chose,

C'est très bien de mettre un sr.Close, mais si pour une raison ou une autre, ton code génère une exception, ton fichier ne sera pas fermé.
Tu pourrais mettre un try...catch...finally, mais le plus simple, est d'utiliser le met clé using :

using (StreamReader sr = new StreamReader(nom))
{
//Fait ce que tu dois faire ave ton sr, à la fin du using, il sera libéré !
}

Amicalement, SharpMao

"C'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!"
(Coluche / 1944-1986 / Pensées et anecdotes)
3
SharpMao Messages postés 1024 Date d'inscription mardi 4 février 2003 Statut Membre Dernière intervention 7 juin 2010 69
6 mai 2008 à 10:41
Hello,

Oui, le problème veanit bien de la concaténation de string.
Désolé de dire ça comme ça, mais ton problème est presque l'exemple parfait de ce qu'il faut éviter avec les string.

A chaque fois que tu fais s+= " ";
il recrée un nouveau string contenant la nouvelle valeur. c'est la répétion de cette création qui devient de plus en plus gourmade en resources.
Avec un StringBuilder, il gère la taille de manière dynamique, et on le voit avec les temps que je t'ai donné, de manière efficace.

Amicalement, SharpMao

"C'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!"
(Coluche / 1944-1986 / Pensées et anecdotes)
3

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
9 mai 2008 à 00:08
Salut,

Si besoin d'une façon imagée de représenter la chose : http://blogs.codes-sources.com/coq/archive/2007/07/28/un-bon-moyen-de-se-souvenir-de-l-ami-stringbuilder.aspx
;-)

/*
coq
MVP Visual C#
CoqBlog
*/
3
tibo76530 Messages postés 24 Date d'inscription mercredi 6 juin 2007 Statut Membre Dernière intervention 15 octobre 2008
5 mai 2008 à 15:26
voici la partie de code ou je pense que ca plante:

StreamReader sr =
new
StreamReader(nom);

String ligne = sr.ReadLine();

while (ligne !=
null){

String[] temp = ligne.Split(
'|');

for (
int i = 0; i < temp.Length; i++){

// textBox3.Text= textBox3.Text + temp[i].ToString()+" ";}
//textBox3.Text textBox3.Text + "\r\n";ligne sr.ReadLine();

}

// Fermeture du StreamReader (attention très important) sr.Close();

merci d'avance
0
tibo76530 Messages postés 24 Date d'inscription mercredi 6 juin 2007 Statut Membre Dernière intervention 15 octobre 2008
6 mai 2008 à 09:26
hello sharpmao
je n'ai  pas mis tout le code, mais j'avais déjà mis un try catch .
sinon, merci de t'etre penché sur mon probleme. je vais essayer de corriger mon code avec tes conseils.
je te dirai ensuite comment je m'en suis sorti.
dans tous les cas, merci !
0
tibo76530 Messages postés 24 Date d'inscription mercredi 6 juin 2007 Statut Membre Dernière intervention 15 octobre 2008
6 mai 2008 à 10:06
bon, je viens de modifier mon code et j'ai fait des tests par rapport à tes conseils. ca marche très bien.
merci encore pour tes tuyaux. le plantage devait venir de la concaténation de String, non?
0
tibo76530 Messages postés 24 Date d'inscription mercredi 6 juin 2007 Statut Membre Dernière intervention 15 octobre 2008
14 mai 2008 à 11:26
re-bonjour à tous.
finalement, je dois afficher mes info dans une autre form, sous forme d'un datagrid view.
malheureusement, j'ai de nouveau des problemes de temps d'executions. je suis en train de chercher, mais je ne vois pas pour le moment.

voici mon code:

form = new Form();
               
                DataGridView dtg1 = new DataGridView();
                dtg1.Size = new System.Drawing.Size(1000, 400);
              
               
               
                /* On recupère le texte complet du fichier */
                if (fi.Exists) // on verifie que le fichier existe
                {
                  
                       using( StreamReader sr = new StreamReader(nom)){
                        String ligne = sr.ReadLine();
                       
                        while (ligne != null)
                        {
                            String[] temp = ligne.Split('|');
                            //dtg1.AutoResizeRows();
                            dtg1.Rows.Add();
                            for(int i=0;i<temp.Length-1;i++)
                           {
                                dtg1.Rows[j].Cells[i].Value = temp[i];
 
                            }
                          
                           
                            ligne = sr.ReadLine();
                        }
                       
                        form.Controls.Add(dtg1);


                        form.Show();
                    }
               


merci d'avance!
0
Rejoignez-nous