Optimisation des performances Python|Méthodes d'optimisation utilisant une correspondance régulière étendue

Scène d'affaires

En utilisant 30 à 40 expressions régulières, 32 millions de chaînes ont été mises en correspondance une par une. À mesure que le nombre d’expressions régulières correspondantes continue d’augmenter, les performances diminuent progressivement.

Optimisation

Pour les expressions régulières fréquemment utilisées, utilisez la méthode suivante :

PATTERN = re.compile("...")


def task(s):
  """被频繁调用的方法"""
  PATTERN.search(s)

Au lieu d'utiliser les 2 méthodes suivantes :

PATTERN = re.compile("...")

def task(s):
  """被频繁调用的方法"""
  re.search(PATTERN, s)
def task(s):
  """被频繁调用的方法"""
  re.search("...", s)
Précautions

Avant d'utiliser le module re, nous avons lu la documentation et appris que pour les expressions régulières fréquemment utilisées, leur initialisation re.compiledans des objets d'expression régulière peut améliorer considérablement les performances. Notre utilisation partout ressemble donc à :

PATTERN = re.compile("...")

def task(s):
  """被频繁调用的方法"""
  re.search(PATTERN, s)

Cependant, après avoir extrait un petit nombre d'échantillons et utilisé les statistiques de cProfile, nous avons quand même constaté qu'il _compileétait exécuté plusieurs fois et prenait beaucoup de temps :

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
......
  4159844    4.635    0.000    5.892    0.000 __init__.py:272(_compile)
......

Ainsi, la suspicion re.search()et d'autres méthodes sont toujours appelées _compile. Vérifiez donc re.search()le code source comme suit :

def search(pattern, string, flags=0):
    """Scan through string looking for a match to the pattern, returning
    a Match object, or None if no match was found."""
    return _compile(pattern, flags).search(string)

Consultez re._compile()le code source comme suit :

_cache = {
    
    }  # ordered!

_MAXCACHE = 512
def _compile(pattern, flags):
    # internal: compile pattern
    if isinstance(flags, RegexFlag):
        flags = flags.value
    try:
        return _cache[type(pattern), pattern, flags]
    ......

Grâce à ce code source, nous comprenons que le processus re.compile()d'analyse en premier et de transmission de l'objet d'expression régulière aux autres méthodes est le même que celui de transmettre re.search()la chaîne aux autres méthodes pour lire le cache.re.search()

Un moyen plus rapide consiste à appeler directement les search()autres méthodes de l’objet d’expression régulière. Tout de suite:

PATTERN = re.compile("...")


def task(s):
  """被频繁调用的方法"""
  PATTERN.search(s)

Après ajustement, _compilela méthode ne prend presque pas de temps.

Je suppose que tu aimes

Origine blog.csdn.net/Changxing_J/article/details/133308468
conseillé
Classement