2010-10-21 36 views
7

Tôi muốn tăng tốc độ đoạn mã sau sử dụng cython:Cython có thể tăng tốc mảng lặp đối tượng không?

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 

Điều duy nhất mà đến với tâm là một cái gì đó như thế này:

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 

Về cơ bản, các giải pháp trong C++ sẽ có mảng của con trỏ đến một số lớp cơ sở với phương thức ảo fun(), sau đó bạn có thể lặp qua nó khá nhanh chóng. Có cách nào để làm điều đó bằng cách sử dụng python/cython?

BTW: sẽ nhanh hơn khi sử dụng mảng 2D của numpy với dtype = object_, thay vì danh sách python?

+0

Hãy thử unrolling 2 vòng bên trong, những con số nhỏ, vì vậy nó sẽ không thêm mã nhiều hơn nữa. Tôi nghĩ rằng sẽ có một cơ hội tốt để giúp đỡ. –

+0

Đây chỉ là một ví dụ, trong mã thực là một kích thước lớn và chỉ được biết ở thời gian chạy – Maxim

Trả lời

5

Hình như mã như thế này cung cấp cho khoảng 20x tăng tốc:

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 

Nó thậm chí kiểm tra, rằng A và B được thừa kế từ cơ sở, có lẽ đó là cách để vô hiệu hóa nó trong phiên bản xây dựng và nhận được thêm tăng tốc

EDIT: Kiểm tra có thể được gỡ bỏ bằng

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

là có lý do nào bạn lưu trữ các đối tượng trong một mảng numpy thay vì một danh sách hoặc cấu trúc dữ liệu khác? – Zephyr

Các vấn đề liên quan