我正在使用Python 2.7的difflib.HtmlDiff.make_table()
函数在内部测试用例运行器的预期文件和实际文件之间生成差异。它们最终出现在HTML测试报告中。
到目前为止这个工作正常 - 直到我添加了一个包含更大文件(~400 KiB)的测试用例,存在很多差异,通常不包含换行符。几乎所有的测试用例都在不到2秒的时间内完成,其中一些复杂的测试用例高达4秒。这个新的传球速度同样快,但需要13分钟(!)才能失败。所有这些时间都用于生成报告。我希望你能看出这是一个什么问题。
尝试证明这一点(可能不是最好的方式,我知道):
s = """import os, difflib
a = [os.urandom(length)]
b = [os.urandom(length)]
difflib.HtmlDiff().make_table(a, b)"""
import timeit
print 'length 100:', timeit.timeit(s, setup='length = 100', number=1)
print 'length 1000:', timeit.timeit(s, setup='length = 1000', number=1)
print 'length 10000:', timeit.timeit(s, setup='length = 10000', number=1)
print 'length 100000:', timeit.timeit(s, setup='length = 100000', number=1)
print 'length 400000:', timeit.timeit(s, setup='length = 400000', number=1)
结果:
length 100: 0.022672659081
length 1000: 0.0125987213238
length 10000: 0.479898318086
length 100000: 54.9947423284
length 400000: 1451.59828412
difflib.ndiff()
(内部由make_table()
使用,据我所知)似乎没有这个问题:
s = """import os, difflib
a = [os.urandom(length)]
b = [os.urandom(length)]
difflib.ndiff(a, b)"""
import timeit
print 'length 100:', timeit.timeit(s, setup='length = 100', number=100)
print 'length 1000:', timeit.timeit(s, setup='length = 1000', number=100)
print 'length 10000:', timeit.timeit(s, setup='length = 10000', number=100)
print 'length 100000:', timeit.timeit(s, setup='length = 100000', number=100)
print 'length 400000:', timeit.timeit(s, setup='length = 400000', number=100)
给我这个:
length 100: 0.0233492320197
length 1000: 0.00770079984919
length 10000: 0.0672924110913
length 100000: 0.480133018906
length 400000: 1.866792587
这看起来非常合理,即它是成比例的。四倍的大小需要四倍的时间。
不知道从哪里开始。我猜想,当存在差异时,HTML生成器会进行大量的回溯(尽管你会认为ndiff()已经处理过了)。我可以告诉它早点中止,放弃并将整个部分标记为“不同”吗?
据我所知,有许多不同的算法可用于生成差异。在这种情况下,我不需要它进行非常深入的分析并尝试在任何地方重新同步。我只是需要它来粗略地告诉我文件中的哪个位置不同,然后在合理的时间范围内终止。
或者,是否有其他生成HTML的Python差异库没有这种最坏的情况?
答案 0 :(得分:0)
与此相关的CPython问题: