Jos*_*ian 24 python arrays performance
在Python中初始化和访问大型数组元素的有效方法是什么?
我想在Python中创建一个包含1亿个条目的数组,无符号的4字节整数,初始化为零.我想要快速数组访问,最好是连续的内存.
奇怪的是,NumPy阵列的表现似乎很慢.我可以尝试其他替代品吗?
有array.array模块,但我没有看到有效分配1亿条目块的方法.
回复评论:
Jos*_*ian 33
我做了一些分析,结果完全违反直觉.对于简单的数组访问操作,numpy和array.array比本机Python数组慢10倍.
请注意,对于数组访问,我正在执行以下形式的操作:
a[i] += 1
Run Code Online (Sandbox Code Playgroud)
简介:
[0]*20000000
numpy.zeros(shape =(20000000,),dtype = numpy.int32)
array.array('L',[0]*20000000)
array.array('L',(0表示范围内的i(20000000)))
Tor*_*rek 13
只是提醒一下Python的整数是如何工作的:如果你通过说明分配一个列表
a = [0] * K
Run Code Online (Sandbox Code Playgroud)
你需要list(sizeof(PyListObject) + K * sizeof(PyObject*)
)的内存和单个整数对象的内存0
.只要列表中的数字保持在V
Python用于缓存的幻数之下,就可以了,因为它们是共享的,即任何指向数字的名称都指向n < V
完全相同的对象.您可以使用以下代码段找到此值:
>>> i = 0
>>> j = 0
>>> while i is j:
... i += 1
... j += 1
>>> i # on my system!
257
Run Code Online (Sandbox Code Playgroud)
这意味着一旦计数超过这个数,你需要的内存是sizeof(PyListObject) + K * sizeof(PyObject*) + d * sizeof(PyIntObject)
,d < K
上面的整数数在哪里V (== 256)
.在64位的系统,sizeof(PyIntObject) == 24
并且sizeof(PyObject*) == 8
,即,最坏的情况下内存消耗32亿个字节.
与numpy.ndarray
或array.array
,内存消耗为初始化之后维持恒定,但你付了透明地创建,如托马斯·沃特斯说,包装对象.也许你应该考虑将更新代码(访问和增加数组中的位置)转换为C代码,或者使用Cython或scipy.weave
.
您不太可能找到比numpy
s更快的东西array
。数组本身的实现与 C 语言中的实现一样高效(并且与 C 语言基本相同array.array
,只是更有用。)
如果您想加快代码速度,则必须这样做。尽管数组的实现很高效,但从 Python 代码访问它会产生一定的开销;例如,索引数组会生成整数对象,这些对象必须动态创建。numpy
提供了许多在 C 中有效实现的操作,但是如果没有看到实际代码的性能不如您想要的,就很难提出任何具体的建议。
如果你无法对你的计算进行矢量化,那么Python/Numpy会很慢.Numpy很快,因为矢量化计算的发生频率低于Python.核心numpy函数都是用C或Fortran编写的.因此sum(a)
,不是具有许多访问的python循环,它是单个低级别C调用.
Numpy的Performance Python演示页面有一个很好的例子,有不同的选项.通过使用较低级别的编译语言Cython或使用矢量化函数(如果可行),您可以轻松获得100倍的增长. 这篇博文显示使用Cython增加了43倍的numpy用例.
归档时间: |
|
查看次数: |
28778 次 |
最近记录: |