J'écris actuellement un script Python pour traiter quelque 10 000 documents d'entrée. Sur la base de la sortie de progrès du script, je remarque que les premiers documents de 400++ sont traités vraiment rapidement, puis le script ralentit bien que les documents d'entrée soient à peu près de la même taille.
Je suppose que cela puisse avoir à faire avec le fait que La majeure partie du traitement des documents est effectuée avec des regextes que je ne sauvegarde pas comme des objets Regex une fois qu'ils ont été compilés. Au lieu de cela, je recompile les regextes chaque fois que j'en ai besoin. P>
Étant donné que mon script a environ 10 fonctions différentes qui utilisent environ 10 à 20 modèles de regex différents, je me demande quelle serait une voie plus efficace dans Python de Évitez de re-compiler les motifs de regex encore et encore (en Perl, je pourrais simplement inclure un modificateur Mon hypothèse est que si je stocke les objets de regex dans Les fonctions individuelles utilisant p> L'objet Regex résultant ne seront pas conservés tant que l'invocation suivante de la fonction pour la prochaine itération (chaque fonction est appelée mais une fois par document). < / p> Création d'une liste globale des regex pré-compilés semble une option peu attrayante car je devrais stocker la liste des regex dans un emplacement différent de mon code que si elles sont réellement utilisées. P> Des conseils ici sur la façon de gérer cela soigneusement et efficacement? P> p> // o code>). p>
4 Réponses :
compilée expression régulière est automatiquement mis en cache par Créer une liste globale de regex pré-compilées semble une option peu attrayante car je devrais stocker la liste des regex dans un emplacement différent de mon code que d'où ils sont réellement utilisés. P>
blockQuote>
Vous pouvez les définir près de l'endroit où ils sont utilisés: juste avant les fonctions qui les utilisent. Si vous réutilisez le même re dans un endroit différent, cela aurait été une bonne idée de la définir globalement dans le monde entier pour éviter de le modifier à plusieurs endroits. P> re.comple code>, re.search code> et re.match code>, mais la taille de cache maximale est 100 à Python 2.7, vous déborde donc du cache. P>
Les caches Regex Caches compilées. Le cache est effacé lorsqu'il atteigne une taille de re._maxcache qui par défaut est de 100. (puisque vous avez 10 fonctions avec 10-20 regexes chacune (c.-à-d. 100-200 expexes), votre ralentissement observé a du sens avec le nettoyage de Le cache.)
Si vous acceptez de changer de variables privées, une solution rapide et sale à votre programme peut être de définir re._maxcache code> à une valeur supérieure: p> import re
re._MAXCACHE = 1000
La dernière fois que j'ai regardé, RECOMPILE maintenait une cache plutôt petite, et quand elle s'est remplie, je viens de le vider. DIY sans limite:
class MyRECache(object):
def __init__(self):
self.cache = {}
def compile(self, regex_string):
if regex_string not in self.cache:
self.cache[regex_string] = re.compile(regex_string)
return self.cache[regex_string]
Ou encore plus succinctement, dérive de dict code> et écraser . __ manquant __ () Code>
@Svenmarnach: Le code que j'ai écrit peut être compris par la personne sans qu'il soit nécessaire de rechercher le __ vaudou __ code> docs.
Il serait intéressant de savoir comment le cache est effacé lorsque sa capacité est utilisée ... Toutes les entrées sont-elles rougées ou juste quelques-unes?
@Pat: Si vous ne croyez pas que "vidé" signifie "rincer toutes les entrées", trouver re.py code> dans votre installation Python (la mine est C: \ python27 \ lib \ re.py) et Recherchez des occurrences de _Cache code> ... Vous devriez trouver _cache = {} code> et _cache.clear () code>
dans l'esprit de "simple est préférable", j'utiliserais une petite fonction d'assistance comme ceci: utilisation: p> Je vous recommande également d'essayer Regex . Parmi d'autres avantages sur le stock Re, son maxcache est de 500 par défaut et ne sera pas supprimé complètement sur le débordement. P> P>
Merci à tous ceux qui ont pris la peine de répondre à ma requête. Je suivrai sur les nombreux indicateurs utiles. Votre soutien est très apprécié!.
Non, cela a à voir avec le fait que votre cache est épuisé i>.
Toutes les fonctions sont-elles appliquées à tous les documents? Parce que si oui, @Larsmans répondit, bien que bon, ne semble pas expliquer le ralentissement après 400 documents. Je suggérerais de profiler plutôt que de deviner ...
Avez-vous vérifié la quantité de mémoire que vous utilisez?
Désolé, je ne connais pas le profilage ... Comment ça marche et que fait-il pour moi?
Profilage: docs.python.org/library/profile.html