SequenceMatcher Python Overhead - utilización de la CPU al 100% y procesamiento muy lento
Pregunta
Estoy utilizando difflib para comparar los archivos en dos directorios (versiones de años consecutivos). En primer lugar, estoy usando filecmp para encontrar los archivos que han cambiado y luego iterativamente usando difflib.SequenceMatcher compararlos y generar un diff html como se explica aquí .
Sin embargo, me parece que el programa está tomando demasiado tiempo para correr y pitón es la utilización de 100% de la CPU. En perfilado tiempo, he encontrado que la seqm.get_opcodes () llamada que está teniendo todo el tiempo.
Cualquier penetración sería apreciada. Gracias!
Código:
#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
Solución
Mi respuesta es un enfoque diferente al problema por completo: Trate de usar un sistema de control de versiones como Git para investigar cómo el directorio cambiado con los años
.Hacer un depósito fuera del primer directorio, a continuación, reemplazar el contenido con el directorio del próximo año y que cometió como un cambio. (O mover el directorio .git al directorio del próximo año, para ahorrar en copia / eliminación). repetir.
A continuación, ejecute gitk, y usted será capaz de ver lo que ha cambiado entre dos revisiones del árbol. Ya sea sólo que un archivo binario cambia, o con un diff para archivos de texto.
Otros consejos
También puede buscar en la biblioteca diff-match-patch
, en mi experiencia que puede ser 10 veces más rápido.
EDIT: Ejemplo mi otra respuesta aquí
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