为什么lists比numpy快?

vhipe2zx  于 2023-08-05  发布在  其他
关注(0)|答案(3)|浏览(80)

为什么在这个例子中列表比numpy快?numpy通常被认为比使用列表更快?但这里的列表似乎快了2倍以上?

$ python main.py 
using_list: 1.8105032444000244 seconds
using_numpy: 4.414405345916748 seconds

个字符
使用Python 3.10.
作为参考,我发现使用numba中的@njit将极大地改进我的numpy代码。但我想知道为什么我的普通numpy版本比列表慢这么多?有没有一种方法可以让我的普通numpy版本更快,而不使用numba

using_numba: 0.6930002999997669 seconds
from numba import njit

@njit
def using_numba(N):
    x = np.ones(N)
    y = np.zeros(N)
    for i in range(1, N):
        y[i] = x[i] + 0.5 * (y[i-1] - x[i])

的字符串

ybzsozfc

ybzsozfc1#

迭代或使用索引逐个元素访问numpy数组效率很低(请参考Why is for loop on native python list faster than for loop on numpy array)。考虑使用numpy的内置函数或方法来加速循环,这可以显着提高大型数组的性能:

def mechanic_using_numpy(N):
    y = np.empty(N, float)
    y[:1] = 1.0
    y[1:] = 0.5
    y.cumprod(out=y)
    np.subtract(1, y, out=y)
    return y

个字符
使用N = 100000进行基准测试:

In [_]: %timeit using_numpy(100000)
44.6 ms ± 227 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [_]: %timeit using_list(100000)
14.3 ms ± 38.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [_]: %timeit mechanic_using_numpy(100000)
286 µs ± 875 ns per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

zpqajqem

zpqajqem2#

为了从numpy中获得好处,您需要以不同的方式进行计算。将其视为对所有值的全局操作,而不是迭代计算:
例如,这个函数给出了相同的结果,但运行速度比使用列表快25倍:

def using_np(N):
    return 1 - 0.5**(np.arange(N))

字符串
如果您需要更快的速度,您可以合并更简单的操作(例如加法和乘法而不是取幂):

def using_np2(N):
    y      = np.ones(N)
    y[0]   = 0
    y[1:] -= np.cumprod(y[1:]/2)
    return y

  • 这个比列表快40倍 *
xlpyo6sf

xlpyo6sf3#

当Numpy可以隐式地并行化操作时,它是快速的。如果没有y[i-1] -> y[i]数据依赖项,可以替换如下循环

for i in range(N):
    y[i] = 0.5*x[i]

字符串

y = 0.5*x


迭代数组的元素并不比迭代列表的元素更快,实际上由于需要在Numpy值类型和Python原生类型之间来回转换,因此速度稍慢。
例如,float值的列表只是引用的列表。y[i]是对存在于列表之外的float值的引用。然而,dtypefloat64数组只是一个表示浮点值集合的二进制blob。像y[i]这样的操作必须提取适当的位,然后使用它们来 * 创建 * 一个要返回的float值。更复杂的表达式,如

y[i] = x[i] + 0.5 * (y[i-1] - x[i])


需要从xy中提取 * 三个 * 这样的值,执行与列表方法相同的运算,然后将结果转换回字节序列以插入回y
对于y = 0.5*x,不存在字节序列到float值的转换,不使用float.__mul__,也不转换回字节序列。所有算法都在Numpy的优化C代码中内部完成。

相关问题