ищу практичные решения для оптимизации скорости разбора текста с помощью python - PullRequest
1 голос
/ 28 мая 2011

Набор строк должен быть проанализирован с набором различных именованных регулярных выражений.

Каждая строка проходит через каждое регулярное выражение, пока не будет найдено совпадение.Когда совпадение найдено, код должен возвращать / давать (именуемые регулярное выражение, значение) пары для каждой строки.

Файлы имеют размер 2 ГБ +, поэтому я ищу несколько идей по улучшению скорости моих анализаторов.

В настоящее время код выполняется через python, но эта часть открыта для изменения.Одним из вариантов является преобразование всего в C для получения большей скорости от PCRE и более быстрого (?) Ввода-вывода, но это медленный маршрут, который трудно поддерживать в будущем.

Я ищу практические решения, такие как:

  • преобразование парсеров в более быстрый язык
  • переход на Cython (?)
  • разбиение файлав нескольких частях и работает поверх нескольких потоков

Ответы [ 3 ]

4 голосов
/ 28 мая 2011

Во-первых, я бы не беспокоился о переключении на другой язык.Альтернативные стратегии могут принести большую выгоду.Механизм регулярных выражений, используемый python, в любом случае написан на C (iirc).

  1. «Оптимизация» регулярных выражений, если, возможно, ваша первая задача.Как это сделать, зависит от вашего текста и выражения. посмотрите для статей и примеров.@ThomasH также поднимает хороший вопрос.
  2. Самый простой способ оптимизировать регулярное выражение - это удалить его;Посмотрите, есть ли возможность переключиться на другие тесты, такие как x in y или line.endswith() и т. Д.
  3. Попробуйте запустить код с помощью pypy .Это может привести к повышению производительности без изменения кода.В вашем случае, хотя выигрыш может быть незначительным, так как производительность зависит от производительности вашего регулярного выражения и файла io.
  4. Одновременная обработка файла в нескольких потоках / процессах , вероятно, будет полезной.Я бы предложил использовать один процесс для чтения файла и передачи строк в очередь, из которой извлекаются несколько процессов.Есть множество способов сделать это.Взгляните на http://effbot.org/zone/wide-finder.htm#a-multi-processor-python-solution
3 голосов
/ 28 мая 2011

Одним из важных моментов для ускорения сопоставления с образцом в Python является попытка использовать одиночное регулярное выражение.Поэтому вместо того, чтобы просматривать список регулярных выражений для каждой строки ввода, объедините регулярные выражения в один с |, а затем примените это регулярное выражение один раз для каждой строки:

reg = re.compile(r'''
    (?<patt1>foo)
    |(?<patt2>bar)
''', re.VERBOSE)

for line in lines:
    mo = reg.search(line)
    if mo:
        yield (mo.lastgroup(), mo.group(mo.lastgroup()))
1 голос
/ 28 мая 2011

Первое, что приходит мне в голову, это то, что вы должны использовать re.compile () , чтобы подготовить все регулярные выражения. Но я думаю, это уже сделано!

Другая вещь, которую следует учитывать, - это иерархическая обработка:

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

Например, если вы ищете тег типа «» в регулярном выражении, это может помочь найти строку в строке для «body» в строке, прежде чем проверять, действительно ли это тег. Вы также можете выполнить поиск "<" перед использованием регулярного выражения, связанного с тегом. </p>

Это также может ускорить обработку, если вы объедините несколько выражений в одно и проверите совпадение. Как замена одной проверки для "{term1}" "{term2}" на "{(term1 | term2)}".

Тогда вы можете попытаться отфильтровать, какое регулярное выражение нужно проверять, определив минимальную длину строки, над которой они работают.

Простые подобные вещи могут ускорить ваше приложение без переключения на другой язык или процессор.

Если возможно, вы также можете попытаться использовать многопоточность. В зависимости от загрузки процессора вы можете обрабатывать каждую вторую строку в два потока, что также может значительно ускорить обработку.

...