2010-10-21 9 views
7

Quiero acelerar el siguiente código utilizando Cython:¿Puede Cython acelerar la matriz de iteración de objetos?

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 

La única cosa que viene a la mente es algo como esto:

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 

Básicamente, la solución en C++ será tener arsenal de punteros a alguna clase base con el método virtual fun(), entonces podría iterar rápidamente. ¿Hay alguna manera de hacerlo usando python/cython?

BTW: ¿sería más rápido usar la matriz 2D de numpy con dtype = object_, en lugar de las listas de python?

+0

Trate desenrollar los bucles internos 2, los números son pequeños, por lo que no añade mucho más código. Creo que hay muchas posibilidades de que numpy ayude. –

+0

Esto es solo un ejemplo, en código real un tamaño es grande y se conoce solo en el tiempo de ejecución – Maxim

Respuesta

5

Parece que un código como éste da aproximadamente 20 veces más veloz:

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 

incluso cheques, que A y B se heredan de base, probablemente hay manera de desactivarlo en las versiones de lanzamiento y obtener aceleración adicional

EDIT: Check podría ser eliminado usando

u = <Base>a[x,y] 
+2

¿hay alguna razón para almacenar los objetos en una matriz numpy en lugar de una lista u otra estructura de datos? – Zephyr

Cuestiones relacionadas