Python SequenceMatcher luminosa - l'utilizzo della CPU al 100% e la lavorazione molto lento
Domanda
Sto usando difflib per confrontare i file in due directory (versioni da anni consecutivi). In primo luogo, io sto usando filecmp per trovare i file che sono stati modificati e quindi in modo iterativo utilizzando difflib.SequenceMatcher per confrontarli e generare un diff html come spiegato qui .
Tuttavia, ritengo che il programma sta impiegando troppo tempo per correre e pitone sta utilizzando il 100% della CPU. Al tempo profiling, ho scoperto che il seqm.get_opcodes () di chiamata che sta prendendo tutto il tempo.
Tutta la comprensione sarebbe apprezzata. Grazie!
Codice:
#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
Soluzione
La mia risposta è un approccio diverso al problema del tutto: Provare a utilizzare un sistema di controllo della versione, come git per studiare come la directory è cambiato nel corso degli anni
.Fare un repository fuori il primo elenco, quindi sostituire il contenuto con la directory del prossimo anno e si impegnano, che come un cambiamento. (O spostare la directory .git alla directory del prossimo anno, per risparmiare sulla copia / eliminazione). ripetere.
Quindi eseguire gitk, e sarete in grado di vedere cosa è cambiato tra due revisioni della pianta. O solo che un file binario è cambiato, o con un diff per file di testo.
Altri suggerimenti
Si può anche provare la diff-match-patch
biblioteca, nella mia esperienza può essere 10 volte più veloce.
EDIT: Esempio mia altra risposta qui
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