当使用范围表达式迭代大型数组时,我应该使用Python内置的range
函数还是numpy的arange
以获得最佳性能?
我的推理如下:
range
可能采用本地实现,因此可能更快。另一方面,arange
返回完整的数组,占用内存,因此可能存在开销。 Python 3的range表达式是一个生成器,不会在内存中保存所有值。
当使用范围表达式迭代大型数组时,我应该使用Python内置的range
函数还是numpy的arange
以获得最佳性能?
我的推理如下:
range
可能采用本地实现,因此可能更快。另一方面,arange
返回完整的数组,占用内存,因此可能存在开销。 Python 3的range表达式是一个生成器,不会在内存中保存所有值。
xrange
/range
,并避免使用np.arange
。C
速度运行。
与此相比,循环numpy数组效率低下。range
或np.arange
创建的索引迭代数组是最糟糕的做法之一,但我不确定你是否真的是这个意思。)import numpy as np
import sys
sys.version
# out: '2.7.3rc2 (default, Mar 22 2012, 04:35:15) \n[GCC 4.6.3]'
np.version.version
# out: '1.6.2'
size = int(1E6)
%timeit for x in range(size): x ** 2
# out: 10 loops, best of 3: 136 ms per loop
%timeit for x in xrange(size): x ** 2
# out: 10 loops, best of 3: 88.9 ms per loop
# avoid this
%timeit for x in np.arange(size): x ** 2
#out: 1 loops, best of 3: 1.16 s per loop
# use this
%timeit np.arange(size) ** 2
#out: 100 loops, best of 3: 19.5 ms per loop
所以在这种情况下,如果使用正确的方法,numpy比使用xrange
快4倍。根据您的问题,numpy可以比4或5倍速度更快。
这个问题的答案解释了使用numpy数组而不是Python列表处理大型数据集的一些其他优点。
xrange
,而range
与其相同。 - Benyamin Jafarinumpy==1.16.4
和python 3.6
中的for x in np.arange(size): x ** 2
,比for x in range(size): x ** 2
更快。 - Benyamin Jafari首先,正如@bmu所提到的,你应该使用向量化计算、ufuncs和索引的组合。确实有一些情况需要明确循环,但这些情况真的很少见。
如果需要明确循环,在Python 2.6和2.7中,你应该使用xrange(见下文)。根据你所说,在Python 3中,range与xrange相同(返回生成器)。所以,也许range对你来说也很好用。
现在,你应该亲自尝试一下 (使用timeit:- 在这里使用ipython "magic function"):
%timeit for i in range(1000000): pass
[out] 10 loops, best of 3: 63.6 ms per loop
%timeit for i in np.arange(1000000): pass
[out] 10 loops, best of 3: 158 ms per loop
%timeit for i in xrange(1000000): pass
[out] 10 loops, best of 3: 23.4 ms per loop
如上所述,通常情况下可以使用numpy向量/数组公式(或ufunc等...),其运行速度快得多,这就是我们所说的“向量编程”。与C相比,它使程序更易于实现(并且更易读),但最终速度几乎一样。
np.arange
是否已经变得更有效率,但与内置的range
相比,它的主要优势在于可以使用浮点数作为起始点:终止点:步长。 - Guimoutelist(range(n))
range(...)
更快。但是,numpy
的np.arange(...)
可以很好地扩展,并在较大的范围内表现更好:
请在此处找到基准代码 here。在 MacBook Pro M1 上使用 Python 3.11 和 numpy
1.23.5 运行。numpy
将是可怕的。反之亦然:一个严重依赖于 numpy
的代码使用 range
感觉不对。np.arange
对于非整数步长有更好的支持。