[stratégie]optimisation d'un parseur
Voici déjà le code, que j'espère pas trop indigest, j'expliquerai mon problème en dessous.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| ByteArrayOutputStream _baos = new ByteArrayOutputStream();
HashMap _keyWords = new HashMap();
String _filepathname ;
private void generateFile() throws Exception{
PrintWriter printwriter = new PrintWriter(_baos);
FileReader filereader = new FileReader(_filepathname);
StringBuffer ligne = new StringBuffer();
StringBuffer champ = new StringBuffer();
int dejaLu = 0; char car = 0; String data = ""; String champmaj="";
String champupdt="";
TraceMgr.traceIn("avant le while");
while (dejaLu <_file.length()){
dejaLu = dejaLu + 1;
car=(char)filereader.read() ;
if (car == '<'){
car=(char)filereader.read();
if (car =='%'){
TraceMgr.traceIn("entrée dans la balise "+dejaLu);
car=(char)filereader.read();
//à la fin de ce while 'champ' contient la chaine de caractère comprise
//entre <% et %>
while (car != '%'){
champ.append(car);
car=(char)filereader.read();
}//fin while
champmaj = champ.toString().toUpperCase();
//chamupupdt contient la valeur à insérer à la place de <%champ%>
champupdt = (String)_keyWords.get(champmaj);
champ=new StringBuffer();//pourquoi pas champ="";
ligne.append(champupdt);
//on dépile jusqu'à lire le caractère après %>
car=(char)filereader.read();
car=(char)filereader.read();
TraceMgr.traceOut("sortie dans la balise "+dejaLu);
}//fin if (car ='%')
else{
ligne.append("<"+car);
}
}//fin if (car == '<')
ligne.append(car);
//en fin de ligne on recopie le buffer 'ligne' dans le printwriter
if (car == '\n'){
printwriter.println(ligne);
ligne.delete(0,ligne.length());
}
}//fin while (dejaLu <_file.length())
//si la dernière ligne n'est pas vide, on la recopie dans le printwriter
if (ligne.length()!=0) {
printwriter.println(ligne);
}
printwriter.close();
filereader.close();
} |
Le but de ce code est de parser un fichier .rtf d'environ 100ko, pour y relever les balises <%champ%> et les remplacer par la valeur de "champ" stockée dans une hashmap.
Le code fonctionne, mais vu la taille du fichier, il prend à peu près 7 secondes à l'exécution.
En faisant quelques traces, je me suis aperçu que ça n'était pas la partie du code consistant à remplacer les balises par leur valeur qui prenait du temps, mais le parcours bète et méchant de la totalité du fichier. En fait, il n'y a qu'une vingtaine de balise dans le fichier.
Voyez-vous une amélioration algorithmique à apporter ? Ou bien peut-être d'autres classes d'entrée/sortie plus performantes que filereader et printwriter à mettre en oeuvre ?
Je vous remercie d'avance pour votre réponse, et même simplement si vous avez eu le courage de me lire jusqu'ici !