蒂姆·彼得斯回答了为什么这很慢,但让我们看看如何改进。
坚持你的例子sum(range(...))(这里比你的例子小10个因子,以便放入内存):import numpy
import array
L = list(range(10**7))
A = array.array('l', L)
N = numpy.array(L)
%timeit sum(L)
10 loops, best of 3: 101 ms per loop
%timeit sum(A)
1 loop, best of 3: 237 ms per loop
%timeit sum(N)
1 loop, best of 3: 743 ms per loop
这样,numpy还需要装箱/拆箱,这会增加额外的开销。要使它快速,必须遵守numpy c代码:%timeit N.sum()
100 loops, best of 3: 6.27 ms per loop
所以从列表解决方案到numpy版本,这是运行时的一个因素16。
我们还要检查创建这些数据结构需要多长时间%timeit list(range(10**7))
1 loop, best of 3: 283 ms per loop
%timeit array.array('l', range(10**7))
1 loop, best of 3: 884 ms per loop
%timeit numpy.array(range(10**7))
1 loop, best of 3: 1.49 s per loop
%timeit numpy.arange(10**7)
10 loops, best of 3: 21.7 ms per loop
净胜球:纽比
还要注意,创建数据结构所需的时间与求和所需的时间(如果不是更多的话)差不多。分配内存很慢。
内存使用情况:sys.getsizeof(L)
90000112
sys.getsizeof(A)
81940352
sys.getsizeof(N)
80000096
因此,每个数字需要8个字节,开销也各不相同。对于我们使用的32位整数的范围来说已经足够了,所以我们可以保护一些内存。N=numpy.arange(10**7, dtype=numpy.int32)
sys.getsizeof(N)
40000096
%timeit N.sum()
100 loops, best of 3: 8.35 ms per loop
但在我的机器上,添加64位整数比添加32位整数快,所以只有在内存/带宽有限的情况下,这才是值得的。