2010-10-21 13 views
7

Ich möchte den folgenden Code verwenden cython beschleunigen:Kann Cython das Array der Objektiteration beschleunigen?

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 

Das einzige, was in den Sinn kommt, ist so etwas wie dieses:

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 

Grundsätzlich wird die Lösung in C++ sein Array haben von Zeigern auf einige Basisklasse mit der virtuellen Methode fun(), dann könnten Sie ziemlich schnell durchlaufen. Gibt es eine Möglichkeit, dies mit Python/Cython zu tun?

BTW: Wäre es schneller, numpys 2D-Array mit dtype = object_ anstelle von Python-Listen zu verwenden?

+0

Versuchen sie es mit Abrollen der 2 inneren Schleifen entfernt werden konnten, sind die Zahlen klein, so dass es viel mehr Code nicht hinzufügen. Ich denke, dass es eine gute Chance gibt, dass numpy hilft. –

+0

Dies ist nur ein Beispiel, in realen Code eine Größe ist groß und nur zur Laufzeit bekannt – Maxim

Antwort

5

Sieht aus wie Code wie folgt über 20x Speedup gibt:

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 

Es prüft sogar, dass A und B von Basis vererbt werden, wahrscheinlich ist es so, wie es in Release zu deaktivieren und

zusätzliche Speedup Builds erhalten

EDIT: prüfen

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

Gibt es einen Grund, warum Sie die Objekte in einem numply Array statt einer Liste oder einer anderen Datenstruktur speichern? – Zephyr

Verwandte Themen