Большая часть причины, ваш код настолько медленно, что if line not in issuesFound:
. Это требует линейного поиска через огромный список.
Вы можете исправить это, добавив set
замеченных проблем (которые можно эффективно искать). Это сокращает время от O (NM) до O (N).
На самом деле, вы можете сделать это еще проще, полностью удалив if
.
Во-первых, вы можете сгенерировать список issuesFound
после факта с помощью ключей от issuesFoundCounter
. Для каждой строки в issuesFoundCounter
вы хотите эту строку, а затем ее knownIssues[line]
. Итак:
issuesFound = list(flatten((line, knownIssues[line]) for line in issuesFoundCounter))
(. Я использую flatten
рецепт от itertools
документов Вы можете скопировать это в ваш код, или вы можете просто написать это с itertools.chain.from_iterable
вместо flatten
.)
и это означает, вы можете просто найти if line not in issuesFoundCounter:
вместо in issuesFound:
, который уже является dict
(и, следовательно, его эффективно искать). Но если вы просто используете setdefault
-или, еще проще, используйте defaultdict
или Counter
вместо dict
- вы можете сделать это автоматически.
Так что, если issuesFoundCounter
является Counter
, все это сводится к этому:
for newLogLine in newLogFile:
for line in knownIssues:
if line in newLogLine:
issuesFoundCounter[line] += 1
И вы можете превратить это в выражение генератора, устраняя медленный иш явного зацикливания в Python с более быстрым зацикливанием внутри интерпретатор. Это только будет, скажем, фиксированный 5: 1 убыстрение, в отличие от ускорения линейной к постоянной от первой половины, но это все-таки стоит задуматься:
issuesFoundCounter = collections.Counter(line
for newLogLine in newLogFile
for line in knownIssues
if line in newLogLine)
Единственная проблема с этим что список issuesFound
теперь находится в произвольном порядке, а не в порядке обнаружения проблем. Если это важно, просто используйте OrderedCounter
вместо Counter
. Там простой рецепт в collections
документы, но для случая, это может быть столь же просто, как:
class OrderedCounter(Counter, OrderedDict):
pass
Почему вы не с помощью встроенного Linux команд? Что-то с небольшим количеством grep, awk и wc magic? – Ben
С моей работой мы работаем над МНОГИМ многих журналов linux.Был надеяться, что сможет отфильтровать определенные группы информации в зависимости от характера проблемы, а затем передать отфильтрованные журналы в нижние команды, которые не так хороши с grep и т. Д. – user1678432
Как побочное примечание, итерация с явными счетчиками, как это делает ваш код труднее читать. Почему не просто 'for newLogLine в newLogFile:' для внешнего цикла? – abarnert