2010-10-21 68 views
7

我想用用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

回答

5

看起來像這樣的代碼提供了有關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