python array太慢_为什么Python的array很慢?

我以为 array.array 比 list 要快,因为array看起来是未装箱的(unboxed)。

然后,我得到了下面的结果:In [1]: import arrayIn [2]: L = list(range(100000000))In [3]: A = array.array('l', range(100000000))In [4]: %timeit sum(L)

1 loop, best of 3: 667 ms per loopIn [5]: %timeit sum(A)

1 loop, best of 3: 1.41 s per loopIn [6]: %timeit sum(L)

1 loop, best of 3: 627 ms per loopIn [7]: %timeit sum(A)

1 loop, best of 3: 1.39 s per loop

这种区别的原因是什么?

其存储是“未装箱的”,但每当你访问一个元素的时候,Python必须将它“装箱”(将之嵌入在一个普通的Python对象中),以便做任何事情。 例如,sum(A)遍历了array,并且一次一个地把每个证书装箱到一个普通的Python int对象中。这要花费时间。而在sum(L)中,所有的装箱都已在创建列表时完成了。

所以最后,数组通常较慢,但是相较需要相当少的内存。

----------------------------------------------------------------------------------------------------------------

这是Python 3最近版本的相关代码,但是相同的基本思想适用于所有CPython实现。

以下是访问列表项的代码:PyObject *

PyList_GetItem(PyObject *op, Py_ssize_t i)

{

/* error checking omitted */

return ((PyListObject *)op) -> ob_item[i];

}

它做的事很少:somelist [i] 仅仅返回列表中的第i个对象(CPython中的所有Python对象都是指向一个结构体的指针,其初始段符合一个PyObject结构体的结构)。下面是具有类型代码 l 的 array 的__getitem__实现:static PyObject *

l_getitem(arrayobject *ap, Py_ssize_t i)

{

return PyLong_FromLong(((long *)ap->ob_item)[i]);

}

原始内存被视为本地平台的元素为C long(长整型)的向量;第 i 个C long 被读出;然后调用PyLong_FromLong() 将本地的C long 包装(“装箱”)成Python long 对象(在Python 3中,它消除了Python 2中 int 和 long 之间的区别,实际上显示为int)。这个装箱必须为Python int对象分配新的内存,并将本地的C long的位写入其中。在原例的上下文中,这个对象的生命周期非常短暂(只是足够让sum()将内容添加到总数中),然后需要更多的时间来释放新的int对象。这就是速度差异的来源,总是来自于,而且总将来自于CPython的实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值