Cython可以加速对象迭代的数组吗?
问题描述:
我想用用Cython加快下面的代码:Cython可以加速对象迭代的数组吗?
class A(object):
cdef fun(self):
return 3
class B(object):
cdef fun(self):
return 2
def test():
cdef int x, y, i, s = 0
a = [ [A(), B()], [B(), A()]]
for i in xrange(1000):
for x in xrange(2):
for y in xrange(2):
s += a[x][y].fun()
return s
,想到的唯一的事情是这样的:
def test():
cdef int x, y, i, s = 0
types = [ [0, 1], [1, 0]]
data = [[...], [...]]
for i in xrange(1000):
for x in xrange(2):
for y in xrange(2):
if types[x,y] == 0:
s+= A(data[x,y]).fun()
else:
s+= B(data[x,y]).fun()
return s
基本上,在C++的解决方案将有数组使用虚拟方法fun()
指向某些基类的指针,那么您可以很快地遍历它。有没有办法使用python/cython做到这一点?
顺便说一句:用dtype = object_而不是python列表使用numpy的2D数组会更快吗?
答
看起来像这样的代码提供了有关20倍速度提升:
import numpy as np
cimport numpy as np
cdef class Base(object):
cdef int fun(self):
return -1
cdef class A(Base):
cdef int fun(self):
return 3
cdef class B(Base):
cdef int fun(self):
return 2
def test():
bbb = np.array([[A(), B()], [B(), A()]], dtype=np.object_)
cdef np.ndarray[dtype=object, ndim=2] a = bbb
cdef int i, x, y
cdef int s = 0
cdef Base u
for i in xrange(1000):
for x in xrange(2):
for y in xrange(2):
u = a[x,y]
s += u.fun()
return s
它甚至检查,A和B都从基地继承,有可能是这样的释放来禁用它建立并获得额外的加速
编辑:检查可以使用
u = <Base>a[x,y]
+2
是否有任何理由将对象存储在一个numpy数组中而不是列表或其他数据结构中? – Zephyr 2017-02-24 03:05:08
尝试展开2个内部循环被移除,数量也少,所以它不会增加太多的代码。我认为numpy很有可能会有所帮助。 – 2010-10-21 14:33:43
这只是一个例子,在真实的代码中,一个大小很大,只有在运行时才知道 – Maxim 2010-10-21 15:08:19