我注意到,Python的内置sum
函数在对一个1000 000个整数的列表求和时大约比for循环快3倍:
import timeit
def sum1():
s = 0
for i in range(1000000):
s += i
return s
def sum2():
return sum(range(1000000))
print 'For Loop Sum:', timeit.timeit(sum1, number=10)
print 'Built-in Sum:', timeit.timeit(sum2, number=10)
# Prints:
# For Loop Sum: 0.751425027847
# Built-in Sum: 0.266746997833
为什么?如何实现sum
?
正如
dwanderson
所建议的,Numpy是一种替代方案。如果你想学数学的话,的确是这样。请参阅此基准:因此使用
numpy
创建列表和求和都要快得多。这主要是因为numpy.array
是为此而设计的,并且比列表更有效。但是,如果我们有一个python列表,那么
numpy
非常慢,因为它从列表到numpy.array
的转换是缓慢的:速度差实际上大于3倍,但是首先要创建一个包含100万个整数的巨大内存列表,从而降低两个版本的速度。把这些从时间试验中分离出来:
现在的速度差已经上升到5倍多了。
一个
for
循环作为解释的Python字节码执行。sum()
完全在C代码中循环。解释字节码和C码之间的速度差很大。此外,如果C代码可以将sum保留为C类型,那么它将确保不会创建新的Python对象;这适用于
int
和float
结果。反汇编的Python版本执行以下操作:
除了解释器循环比C慢之外,
INPLACE_ADD
将创建一个新的整数对象(超过255,CPython将小的int
对象缓存为singleton)。您可以在Python mercurial代码存储库中看到C implementation,但它在注释中明确声明:
您可以在^{} 中看到源代码。它对
int
s和float
s有特殊的情况,但是由于总和很快溢出到long
s,这可能不会对性能产生重大影响。一般的case逻辑与您在Python中编写的非常相似,只是在C中。加速最有可能是因为它不必经历所有字节码解释和错误处理开销:相关问题 更多 >
编程相关推荐