2024-03-29 08:49:07 发布
网友
在Python中,初始化和访问大型数组元素的有效方法是什么?
我想用Python创建一个数组,其中有1亿个条目,无符号的4字节整数,初始化为零。我想要快速的数组访问,最好是连续内存。
奇怪的是,NumPy数组的执行速度似乎非常慢。我可以试试别的办法吗?
有一个array.array模块,但是我看不到一个有效地分配1亿个条目块的方法。
对评论的答复:
我做了一些分析,结果完全违背直觉。 对于简单的数组访问操作,numpy和array.array比原生Python数组慢10倍。
注意,对于数组访问,我正在执行以下形式的操作:
a[i] += 1
个人资料:
[0]*2000万
numpy.zeros(shape=(20000000,),dtype=numpy.int32)
array.array('L',[0]*20000000)
array.array('L',(0表示范围(20000000)内的i)
只是提醒一下Python的整数是如何工作的:如果通过
a = [0] * K
您需要列表的内存(sizeof(PyListObject) + K * sizeof(PyObject*))和单个整数对象的内存0。只要列表中的数字保持在Python用于缓存的魔法数字V以下,就可以了,因为这些数字是共享的,即任何指向数字的名称n < V都指向完全相同的对象。您可以使用以下代码段找到此值:
sizeof(PyListObject) + K * sizeof(PyObject*)
0
V
n < V
>>> i = 0 >>> j = 0 >>> while i is j: ... i += 1 ... j += 1 >>> i # on my system! 257
这意味着一旦计数超过这个数字,您需要的内存就是sizeof(PyListObject) + K * sizeof(PyObject*) + d * sizeof(PyIntObject),其中d < K是V (== 256)上的整数数。在64位系统上,sizeof(PyIntObject) == 24和sizeof(PyObject*) == 8,即最坏情况下的内存消耗是320000000字节。
sizeof(PyListObject) + K * sizeof(PyObject*) + d * sizeof(PyIntObject)
d < K
V (== 256)
sizeof(PyIntObject) == 24
sizeof(PyObject*) == 8
使用numpy.ndarray或array.array,初始化后内存消耗是恒定的,但是您要为透明创建的包装器对象付费,正如Thomas Wouters所说。可能,您应该考虑使用Cython或^{}将更新代码(访问并增加数组中的位置)转换为C代码。
numpy.ndarray
array.array
试试这个:
x = [0] * 100000000
在我的机器上执行只需几秒钟,访问接近即时。
我做了一些分析,结果完全违背直觉。 对于简单的数组访问操作,numpy和array.array比原生Python数组慢10倍。
注意,对于数组访问,我正在执行以下形式的操作:
个人资料:
[0]*2000万
numpy.zeros(shape=(20000000,),dtype=numpy.int32)
array.array('L',[0]*20000000)
array.array('L',(0表示范围(20000000)内的i)
只是提醒一下Python的整数是如何工作的:如果通过
您需要列表的内存(
sizeof(PyListObject) + K * sizeof(PyObject*)
)和单个整数对象的内存0
。只要列表中的数字保持在Python用于缓存的魔法数字V
以下,就可以了,因为这些数字是共享的,即任何指向数字的名称n < V
都指向完全相同的对象。您可以使用以下代码段找到此值:这意味着一旦计数超过这个数字,您需要的内存就是
sizeof(PyListObject) + K * sizeof(PyObject*) + d * sizeof(PyIntObject)
,其中d < K
是V (== 256)
上的整数数。在64位系统上,sizeof(PyIntObject) == 24
和sizeof(PyObject*) == 8
,即最坏情况下的内存消耗是320000000字节。使用} 将更新代码(访问并增加数组中的位置)转换为C代码。
numpy.ndarray
或array.array
,初始化后内存消耗是恒定的,但是您要为透明创建的包装器对象付费,正如Thomas Wouters所说。可能,您应该考虑使用Cython或^{试试这个:
在我的机器上执行只需几秒钟,访问接近即时。
相关问题 更多 >
编程相关推荐