Y a-t-il une méthode plus rapide que l'exploitation des classes Pattern et Matcher du package java.util.regex, pour la recherche de chaines génériques en Java ?
Y a-t-il une méthode plus rapide que l'exploitation des classes Pattern et Matcher du package java.util.regex, pour la recherche de chaines génériques en Java ?
Je précise un peu ma demande :
J’ai la boucle suivante :
qui est elle-même appelée dans une boucle sur l’ensemble des lignes d’un fichier (pouvant aller jusqu’à 2Go).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 res = ligne; // Parcours de l'ensemble des patterns à remplacer for(Iterator i = listeDeRemplacement.iterator() ; i.hasNext() ; ) { elt = (ElementDeRemplacement)i.next(); pattern = Pattern.compile(elt.chaineARemplacer); matcher = pattern.matcher(res); if(matcher.find()) { res = matcher.replaceAll(elt.chaineDeRemplacement); } }
Afin de gagner un peu de temps, j’ai directement stocké l’objet pattern dans la collection parcourue. J’obtiens donc :
Mais arrivé là, je dois admettre que je suis à cours d’idées, et le temps de traitement est encore colossal
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 res = ligne; for(Iterator i = listeDeRemplacement.iterator() ; i.hasNext() ; ) { elt = (ElementDeRemplacement)i.next(); matcher = elt.patternARemplacer.matcher(res); if(matcher.find()) { res = matcher.replaceAll(elt.chaineDeRemplacement); } }.
Salut,
Pourquoi ne pas utiliser directement la méthode replaceAll() de String ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 res = ligne; // Parcours de l'ensemble des patterns à remplacer for(Iterator i = listeDeRemplacement.iterator() ; i.hasNext() ; ) { elt = (ElementDeRemplacement)i.next(); res = res.replaceAll(elt.chaineARemplacer, elt.chaineDeRemplacement); }
a++
Parce qu’il me semblait que le replaceAll() de String correspondait à un appel de Pattern.compile(regex).matcher(str).replaceAll(repl).
J’en ai donc déduis que le faire moi-même pourrait être plus rapide.
Suite au doute levé, je viens de vérifier. Les perf d’exploitation du replaceAll() de String sont effectivement équivalente au fait de placer le Pattern.compile() dans la boucle.
Dans mon cas, cela multiplie par 3 le temps de traitement.
En effet replaceAll() de String correspond bien à un appel de Pattern.compile(regex).matcher(str).replaceAll(repl)... donc cela ne change rien au contraire...
Tu peux toutefois supprimer le matcher.find() qui est inutile car c'est géré par matcher.replaceAll(), cela peut améliorer les performances car le pattern est recherché une fois de trop :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 res = ligne; // Parcours de l'ensemble des patterns à remplacer for(Iterator i = listeDeRemplacement.iterator() ; i.hasNext() ; ) { elt = (ElementDeRemplacement)i.next(); pattern = Pattern.compile(elt.chaineARemplacer); matcher = pattern.matcher(res); res = matcher.replaceAll(elt.chaineDeRemplacement); }
Sinon par curiosité, à quoi ressemble les lignes et les patterns que tu recherches ???
a++
Je dois admettre que cela simplifie l’écriture, mais je ne constate aucune amélioration des performances.
Pour satisfaire ta curiosité, et au cas ou cela amènerait à quelqu’inspiration, voici un exemple de ligne traitée :
Et les patterns que je recherche sont du type :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 CalculTotalFacture => IndentifiantClient (262) / DateFacturation (27/01/2004)
Bref, je cherche à supprimer les identifiants du fichier.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 elt.chaineARemplacer elt.chaineDeRemplacement IndentifiantClient \(.{1,10}\) IndentifiantClient DateFacturation \(.*\) DateFacturation
Sachant que pour chaque ligne de mon fichier, j’ai en moyenne 50 à 80 patterns à traiter.
Ah oui quand mêmeEnvoyé par jproto
Sur 2Go j'imagine que ca doit prendre pas mal de temps...
Essaye de voir si tu ne peux pas regrouper les patterns...
Par exemple dans ce cas, et si tu n'as rien d'autre entre parenthèses dans ton fichier, tu pourrais regrouper les deux patterns en 1 seul afin de supprimer toutes les parenthèses :
Sinon si tes patterns sont plus compliqué que ca (ce que je crains), il faudrait peut-être voir si ce ne serait pas mieux d'utiliser un analyseur syntaxique afin de mofidier la chaine en un seul passage (ou lieu d'un passage par Pattern). Tu peux trouver des outils pour cela dans la boite à outils Java (antlr, cup, JFlex et Javacc), mais par contre je ne les ai jamais utilisé...
Code : Sélectionner tout - Visualiser dans une fenêtre à part replaceAll("\(.*?\)", "");
a++
En fait, mes patterns sont un peu plus compliqués. Il doit m’être possible d’en regrouper quelques un (et je vais m’y atteler), mais toute la subtilité du traitement réside évidement (et malheureusement) dans le fait de conserver la majorité des identifiants du fichiers (valeurs placées entre parenthèses). D’ailleurs, les patterns ne sont pas écris en dur, mais fournis par un fichier de paramétrage.
En revanche, je dois admettre ne pas avoir pensé à explorer du côté de la boite à outils. Voici une étude qui devrait m’occuper un petit moment.
Merci beaucoup pour l’orientation.
Partager