Определение проблемы: учитывая текст длиной n
символов и список терминов (которые могут быть регулярными выражениями) длины t
, найдите и подсчитайте все вхождения терминов в тексте.Оптимизация соответствия регулярных выражений для длинного списка выражений
Вот наивная реализация для этого:
class WordFrequency(TextAnalysis):
"""Determines the frequency of words from a vocabulary in a given text"""
def __init__(self, vocabulary, text):
"""
:param vocabulary: contains the words (e.g. list)
:param text: the analysed text
"""
self.text = text
self.vocabulary = vocabulary
self.matches = {}
def run(self):
"""
:return: self for method chaining
"""
ltext = self.text.lower()
self.freq = {} # word -> absolute frequency
for word in self.vocabulary:
matches = re.findall(r'\b' + word + r'\b', ltext)
self.matches[word] = [match for match in matches] #.lstrip() for match in matches]
self.freq[word] = len(matches)
return self
Теперь это занимает около 6 секунд для текста длиной ок 35000 символов и список ок. 5000, что слишком медленно. Похоже, что временная сложность этого составляет O(t * n)
, потому что для каждого из условий t
текст нужно сканировать один раз. Есть ли очевидная ошибка производительности здесь? Каковы возможные оптимизации и/или лучшие алгоритмы?
Этот вопрос должен быть перенесен на http://codereview.stackexchange.com – danidee
Почему вы добавляете копию списка совпадений в свою коллекцию? Вы знаете частоту, и вы знаете слово ... Если вы не хотите считать без учета регистра (что вы в настоящее время нет) и сохранить исходные совпадения. И даже для этого вам не нужно делать дополнительную копию - 'self.matches [word] = matches' будет намного быстрее. –