Накладные расходы Python SequenceMatcher — 100% загрузка ЦП и очень медленная обработка

StackOverflow https://stackoverflow.com/questions/1870646

  •  18-09-2019
  •  | 
  •  

Вопрос

Я использую difflib для сравнения файлов в двух каталогах (версии за несколько лет подряд).Во-первых, я использую filecmp, чтобы найти файлы, которые были изменены, а затем итеративно использую difflib.SequenceMatcher, чтобы сравнить их и сгенерировать разницу в формате html, как объяснено. здесь.

Однако я обнаружил, что программа выполняется слишком долго, а Python использует 100% процессорного времени.Профилируя время, я обнаружил, что seqm.get_opcodes() звонок, который занимает все время.

Любое понимание будет оценено по достоинству.Спасибо !

Код:

#changed_set contains the files to be compared
for i in changed_set:
  oldLines = open(old_dir +"/" + i).read()
  newLines = open(new_dir +"/" + i).read()
  seqm = difflib.SequenceMatcher(lambda(x): x in string.whitespace, oldLines, newLines)
  opcodes = seqm.get_opcodes() #XXX: Lots of time spent in this !
  produceDiffs(seqm, opcodes)
  del seqm
Это было полезно?

Решение

Мой ответ - совершенно другой подход к проблеме:Попробуйте использовать систему контроля версий, например git, чтобы выяснить, как каталог менялся с течением времени.

Создайте репозиторий из первого каталога, затем замените его содержимое каталогом следующего года и зафиксируйте его как изменение.(или переместите каталог .git в каталог следующего года, чтобы сэкономить на копировании/удалении).повторить.

Затем запустите gitk, и вы сможете увидеть, что изменилось между любыми двумя ревизиями дерева.Либо просто изменился бинарный файл, либо с дифом текстовых файлов.

Другие советы

Вы также можете попробовать diff-match-patch Библиотека, по моему опыту, это может быть в 10 раз быстрее.

РЕДАКТИРОВАТЬ: Пример мой другой ответ здесь

from diff_match_patch import diff_match_patch

def compute_similarity_and_diff(text1, text2):
    dmp = diff_match_patch()
    dmp.Diff_Timeout = 0.0
    diff = dmp.diff_main(text1, text2, False)

    # similarity
    common_text = sum([len(txt) for op, txt in diff if op == 0])
    text_length = max(len(text1), len(text2))
    sim = common_text / text_length

    return sim, diff
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top