作为对我的问题的回答找到两个列表相同的基于 1 的位置,我得到了使用 C 库 itertools 来加快速度的提示。
为了验证我使用 cProfile 编写了以下测试:
from itertools import takewhile, izip
def match_iter(self, other):
return sum(1 for x in takewhile(lambda x: x[0] == x[1],
izip(self, other)))
def match_loop(self, other):
element = -1
for element in range(min(len(self), len(other))):
if self[element] != other[element]:
element -= 1
break
return element +1
def test():
a = [0, 1, 2, 3, 4]
b = [0, 1, 2, 3, 4, 0]
print("match_loop a=%s, b=%s, result=%s" % (a, b, match_loop(a, b)))
print("match_iter a=%s, b=%s, result=%s" % (a, b, match_iter(a, b)))
i = 10000
while i > 0:
i -= 1
match_loop(a, b)
match_iter(a, b)
def profile_test():
import cProfile
cProfile.run('test()')
if __name__ == '__main__':
profile_test()
函数 match_iter() 正在使用 itertools,而函数 match_loop() 是我在使用普通 python 之前实现的。
函数 test() 定义了两个列表,打印带有两个函数结果的列表以验证它是否正常工作。两个结果都具有预期值 5,即列表的长度相等。然后它在这两个函数上循环 10,000 次。
最后,使用 profile_test() 分析整个事情。
我学到的是 izip 没有在 python3 的 itertools 中实现,至少在我使用的 debian wheezy whitch 中没有实现。所以我用python2.7运行了测试
结果如下:
python2.7 match_test.py
match_loop a=[0, 1, 2, 3, 4], b=[0, 1, 2, 3, 4, 0], result=5
match_iter a=[0, 1, 2, 3, 4], b=[0, 1, 2, 3, 4, 0], result=5
180021 function calls in 0.636 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.636 0.636 <string>:1(<module>)
1 0.039 0.039 0.636 0.636 match_test.py:15(test)
10001 0.048 0.000 0.434 0.000 match_test.py:3(match_iter)
60006 0.188 0.000 0.275 0.000 match_test.py:4(<genexpr>)
50005 0.087 0.000 0.087 0.000 match_test.py:4(<lambda>)
10001 0.099 0.000 0.162 0.000 match_test.py:7(match_loop)
20002 0.028 0.000 0.028 0.000 {len}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
10001 0.018 0.000 0.018 0.000 {min}
10001 0.018 0.000 0.018 0.000 {range}
10001 0.111 0.000 0.387 0.000 {sum}
让我想知道的是,查看 cumtime 值,我的普通 python 版本对于 10,000 个循环的值为 0.162 秒,而 match_iter 版本需要 0.434 秒。
一方面,python 非常快,很棒,所以我不必担心。但这是否正确,C 库完成工作所需的时间是简单 python 代码的两倍多?还是我犯了一个致命的错误?
为了验证我也用 python2.6 运行了测试,这似乎更快,但循环和 itertools 之间的区别相同。
谁有经验并愿意提供帮助?