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数组会更快吗?

+0

尝试展开2个内部循环被移除,数量也少,所以它不会增加太多的代码。我认为numpy很有可能会有所帮助。 – 2010-10-21 14:33:43

+0

这只是一个例子,在真实的代码中,一个大小很大,只有在运行时才知道 – Maxim 2010-10-21 15:08:19

看起来像这样的代码提供了有关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