Быстрый цикл по двум спискам, сравнивающий шаблон регулярных выражений, используя значения из одного списка со значениями в другом списке - PullRequest
0 голосов
/ 31 октября 2019

В настоящее время я пытаюсь решить сложную проблему в Python. Для установки сцены я использую Let's Encrypt, поэтому у меня есть (posix) пути к действующему каталогу, и у меня есть список доменов из CMS.

Я пытаюсь сравнить домены спути, которые требуют совпадения регулярного выражения, содержащего значение из первого списка, потому что пути будут содержать доменные имена, но я не могу / не понимаю, как бы я сделал пересечение наборов, потому что значения не совпадают, но это очень болезненно медленно с традиционным циклом for (когда у вас> 12000 доменных имен и> 10000 сертификатов (путей)).

Итак, некоторый пояснительный код:

import re

from cryptography.x509 import load_pem_x509_certificate
from cryptography.hazmat.backends import default_backend, openssl


all_domains = function_that_returns_domains_as_list()
all_paths = function_that_returns_certificate_paths()
nocert_list = list()


def cert_check(path):
    cert = load_pem_x509_certificate(path.read_bytes(), default_backend())
    cur_date = datetime.now()
    end_date = cert.not_valid_after
    ... # More logic and functions for checking if the certificate has expired etc.


def path(domain):
    for path in all_paths:
        if path.match(f"*/{domain}*"):
            return path


def check_domain_certs():
    for domain in all_domains:
        path_check = path(domain)
        if not path_check:
            nocert_list.append(domain)
        if path_check:
            cert_path = path_check
            cert_check(cert_path)

Даже если я не вызову функцию cert_check в функции check_domain_certs и вместо этого добавлю путь к списку для вызова вне цикла и функции check_domain_certs, сам цикл занимает много времени (я запускал его, пока печатал это сообщениеи он только что закончился через ~ 30 минут. Вероятно, что-то связано с тем, что цикл приходится совершать около 120 миллионов раз. )

Сегодня я пробежал много кроличьих стеков, поэтому на самом деле я обращаюсь к сообществу за помощью.

Ответы [ 2 ]

0 голосов
/ 04 ноября 2019

Если поиск не удался чаще, чем успешен, это может быть быстрее:

def check_domain_certs():
    all_paths_as_string = str(set(all_paths))
    for domain in all_domains:
        if not domain in all_paths_as_string:
            nocert_list.append(domain)
        else:
            cert_path = path(domain)  # full search returning cert path
            cert_check(cert_path)
            ...
0 голосов
/ 31 октября 2019

Вещи, которые вы можете попробовать:

  • Поиск оптимизации в Python. (Использование встроенных Python может помочь!)
  • Обычно понимание списка лучше, чем для циклов

Мой общий совет - использовать списокпонимание с Cython . Сначала используйте понимание списка, а затем проверьте оптимизацию Cython с помощью файлов .pyx и выполните цитонизацию.

В общем, Cython переводит код Python в C. Особенно циклы в Python работают значительно быстрее с Cython. Вы можете посмотреть одно из видео * Sentdex , объясняющее общие принципы для Cython. Как вы могли видеть в 23:20 видео, оно вносит значительные изменения, примерно в 100 раз быстрее, чем традиционный цикл Python.

...