Python SequenceMatcher Frais généraux - utilisation du processeur à 100% et le traitement très lent
Question
J'utilise difflib pour comparer les fichiers dans deux répertoires (versions des années consécutives). Tout d'abord, je suis en utilisant filecmp pour trouver des fichiers qui ont été modifiés et itérativement en utilisant difflib.SequenceMatcher pour les comparer et générer une diff html comme expliqué .
Cependant, je trouve que le programme prend trop de temps pour exécuter et python est en utilisant 100% du CPU. Le profilage de temps, je l'ai trouvé que le seqm.get_opcodes () appel qui prend tout le temps.
Toute idée serait appréciée. Merci!
Code:
#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
La solution
Ma réponse est une approche différente du problème tout à fait: Essayez d'utiliser un système de contrôle de version comme git pour enquêter sur la façon dont le répertoire a changé au fil des ans
.Faire un dépôt sur le premier répertoire, puis remplacer le contenu de la prochaine année, répertoire et engage que comme un changement. (Ou déplacer le répertoire .git au répertoire de l'année prochaine, pour économiser sur la copie / suppression). répéter.
Ensuite, exécutez gitk, et vous serez en mesure de voir ce qui a changé entre deux révisions de l'arbre. Soit juste qu'un fichier binaire modifié, ou avec un diff pour les fichiers texte.
Autres conseils
Vous pouvez également essayer la bibliothèque diff-match-patch
, dans mon expérience, il peut être 10 fois plus rapide.
EDIT: Exemple mon autre réponse
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