Question

Chaque fois qu'un fichier python contenant un grand nombre d'expressions régulières statiques est importé, les cycles cpu sont passés à la compilation des chaînes dans leurs machines d'état représentatives en mémoire.

a = re.compile("a.*b")
b = re.compile("c.*d")
...

Question: Est-il possible de stocker ces expressions régulières dans un cache sur disque de manière pré-compilée pour éviter de devoir exécuter les compilations regex à chaque importation?

La sélection de l’objet a simplement pour but de provoquer la compilation:

>>> import pickle
>>> import re
>>> x = re.compile(".*")
>>> pickle.dumps(x)
"cre\n_compile\np0\n(S'.*'\np1\nI0\ntp2\nRp3\n."

Et les objets sont incontournables:

>>> import marshal
>>> import re
>>> x = re.compile(".*")
>>> marshal.dumps(x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: unmarshallable object
Était-ce utile?

La solution

  

Est-il possible de stocker ces expressions régulières dans un cache sur disque de manière pré-compilée pour éviter de devoir exécuter les compilations regex à chaque importation?

Pas facilement. Vous devez écrire un sérialiseur personnalisé qui se raccorde à l'implémentation C sre du moteur d'expression régulière Python. Les avantages en termes de performances seraient largement compensés par le temps et les efforts requis.

D'abord, avez-vous réellement profilé le code? Je doute que la compilation de regex soit une partie importante de l'exécution de l'application. N'oubliez pas qu'ils ne sont compilés que lors de la première importation du module dans l'exécution en cours. Par la suite, le module et ses attributs sont mis en mémoire cache.

Si vous avez un programme qui se crée une fois, compile un grand nombre de regex, puis se ferme, vous pouvez le réorganiser pour effectuer plusieurs tests en une seule invocation. Ensuite, vous pouvez réutiliser les expressions rationnelles, comme ci-dessus.

Enfin, vous pouvez compiler les expressions rationnelles dans des machines d'état basées sur C, puis les lier avec un module d'extension. Bien que cela soit probablement plus difficile à maintenir, cela éliminerait entièrement la compilation regex de votre application.

Autres conseils

Notez que chaque module ne s'initialise qu'une seule fois au cours de la vie d'une application, quel que soit le nombre de fois que vous l'importez. Donc, si vous compilez vos expressions dans la portée globale du module (c'est-à-dire pas dans une fonction), tout va bien.

Tout d’abord, c’est une limitation claire dans le module python re. Cela limite les expressions rationnelles raisonnables. La limite est plus grande avec les processus de longue durée et plus petite avec les processus de courte durée tels que les applications en ligne de commande.

Il y a quelques années, je l'ai examiné et il est possible d'extraire le résultat de la compilation, de le conserver au vinaigre, puis de le défaire et de le réutiliser. Le problème est qu’il nécessite l’utilisation des éléments internes sre.py et ne fonctionnera donc probablement pas dans différentes versions de python.

J'aimerais avoir ce genre de fonctionnalité dans ma boîte à outils. J'aimerais aussi savoir s'il existe des modules distincts qui pourraient être utilisés à la place.

Le module shelve semble fonctionner correctement:


import re
import shelve
a_pattern = "a.*b"
b_pattern = "c.*d"
a = re.compile(a_pattern)
b = re.compile(b_pattern)

x = shelve.open('re_cache')
x[a_pattern] = a
x[b_pattern] = b
x.close()

# ...
x = shelve.open('re_cache')
a = x[a_pattern]
b = x[b_pattern]
x.close()

Vous pouvez ensuite créer une belle classe wrapper qui gère automatiquement la mise en cache pour vous afin qu'elle devienne transparente pour l'utilisateur ... un exercice laissé au lecteur.

Ouvrez /usr/lib/python2.5/re.py et recherchez "def _compile". Vous trouverez le mécanisme de cache interne de re.py.

Il est possible de placer chaque regex (ou groupe de regex) dans un fichier séparé, puis d'importer dynamiquement le fichier dont vous avez besoin à l'aide du module imp. Je doute que cela évolue très bien, mais cela pourrait être ce dont vous avez besoin.

Hum,

Le rayon ne contient-il pas de cornichons?

Quoi qu’il en soit, je suis d’accord avec les réponses précédentes. Puisqu'un module n'est traité qu'une seule fois, je doute que la compilation des expressions rationnelles soit le goulot d'étranglement de votre application. Et le module Python re est méchant rapide car il est codé en C: -)

Mais la bonne nouvelle est que Python a créé une belle communauté. Je suis donc sûr que vous pouvez trouver quelqu'un qui pirate actuellement les outils, exactement ce dont vous avez besoin.

J'ai googlé pendant 5 secondes et trouvé: http: //home.gna. org / oomadness / fr / cerealizer / index.html .

Je ne sais pas s’il le fera mais sinon, bonne chance dans vos recherches: -)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top