gpt4 book ai didi

python - 列表(numpy.array)缓慢的原因是什么?

转载 作者:太空宇宙 更新时间:2023-11-04 00:19:44 25 4
gpt4 key购买 nike

众所周知,如果 a 是一个 numpy 数组,那么 a.tolist()list(a) 快,例如:

>>> import numpy as np
>>> big_np=np.random.randint(1,10**7,(10**7,))

>>> %timeit list(big_np)
1 loop, best of 3: 869 ms per loop
>>> %timeit big_np.tolist()
1 loop, best of 3: 306 ms per loop

这意味着,朴素的 list(a) 版本比特殊函数 tolist() 慢大约 3 倍。

但是,将其与内置 array 模块的性能进行比较:

>>> import array
>>> big_arr=array.array('i', big_np)
>>> %timeit list(big_arr)
1 loop, best of 3: 312 ms per loop

我们可以看到,可能应该说,list(a)tolist() 快,因为 array.array 与特殊函数一样快。

另一个观察:array.array-module 和 tolist 受益于 small-integer-pool (即当值在 [-5, 256] 范围内时),但 list(a) 不是这种情况:

##only small integers:
>>> small_np=np.random.randint(1,250, (10**7,))
>>> small_arr=array.array('i', small_np)

>>> %timeit list(small_np)
1 loop, best of 3: 873 ms per loop
>>> %timeit small_np.tolist()
10 loops, best of 3: 188 ms per loop
>>> %timeit list(small_arr)
10 loops, best of 3: 150 ms per loop

正如我们所见,较快的版本快了大约 2 倍,但较慢的版本和以前一样慢。

我的问题:与 list(array.array) 相比,是什么让 list(numpy.array) 变慢了?

编辑:

再观察一下,对于 Python2.7,如果整数越大(即 int32 不能容纳),则需要更长的时间:

>>> very_big=np.random.randint(1,10**7,(10**7,))+10**17
>>> not_so_big=np.random.randint(1,10**7,(10**7,))+10**9
>>> %timeit very_big.tolist()
1 loop, best of 3: 627 ms per loop
>>> %timeit not_so_big.tolist()
1 loop, best of 3: 302 ms per loop

但仍然比慢速列表版本更快。

最佳答案

这是解释您对小整数池的观察的部分答案:

>>> a = np.arange(10)
>>> type(list(a)[0])
<class 'numpy.int64'>
>>> type(a.tolist()[0])
<class 'int'>

正如我们所见,tolist 似乎尝试创建原生 python 类型的元素,而数组迭代器(这是列表构造函数使用的)不会打扰。

事实上,tolist(来源 here)的 C 实现使用 PyArray_GETITEM which is the equivalent to Python arr[index].item(), not - as one might assume - arr[index]

关于python - 列表(numpy.array)缓慢的原因是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49629849/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com