我正在使用Toby Segaran的集体智能代码进行基因编程,因此我想使用Cython加快速度。我开始意识到我可能比我第一次尝试Cython项目要花的钱还多。我已经在Google上搜索了有关如何使它起作用的答案,但是似乎找不到合适的示例组合。
这是有问题的实际代码:
# Function Wrapper Code
class fwrapper:
def __init__(self, funct, params, name):
self.function = funct
self.params = params
self.name = name
# Functions with 2 parameters
addw = fwrapper(lambda p: p[0] + p[1], 2, 'add')
subw = fwrapper(lambda p: p[0] - p[1], 2, 'subtract')
mulw = fwrapper(lambda p: p[0] * p[1], 2, 'multiply')
# If and > Function
def iffunc(l):
if l[0] > 0:
return l[1]
else:
return l[2]
ifw = fwrapper(iffunc, 3, 'if')
def isgreater(l):
if l[0] > l[1]:
return 1
else:
return 0
gtw = fwrapper(isgreater, 2, 'isgreater')
# List of possible functions
flist = [addw, mulw, ifw, gtw, subw]
因此,因为Toby使用Python类作为其在遗传编程算法中使用的函数的包装,所以我必须首先对类本身进行“ Cythonize”(我并不是说实际的cythonize调用)。但是函数包装器类传递了一个函数。更糟糕的是,传递进来的那个函数需要一个单独的参数,即Python列表。
因此,由于它需要一些我似乎无法理解的高级主题,因此试图在Cython中加快速度是有问题的。
第一个问题:我不知道如何将c样式的函数传递给此类的“ cythonized”版本。此解决方案可以使用,但不是很快,因为它仍将我传入的函数视为慢速python函数:
# Function Wrapper Code
cdef class fwrapper:
cdef public object function
cdef public int params
cdef public object name
def __init__(self, funct, int params, name):
self.function = funct
self.params = params
self.name = name
# Functions with 2 parameters
cdef add(double param1, double param2):
return param1 + param2
addw = fwrapper(add, 2, 'add')
cdef subtract(double param1, double param2):
return param1 - param2
subw = fwrapper(subtract, 2, 'subtract')
cdef multiply(double param1, double param2):
return param1 * param2
mulw = fwrapper(multiply, 2, 'multiply')
# If and > Function - 3 parameter functions
cdef iffunc(double param1, double param2, double param3):
if param1 > 0:
return param2
else:
return param3
ifw = fwrapper(iffunc, 3, 'if')
cdef isgreater(double param1, double param2):
if param1 > param2:
return 1
else:
return 0
gtw = fwrapper(isgreater, 2, 'isgreater')
# List of possible functions
flist = [addw, mulw, ifw, gtw, subw]
我尝试与ctypedef一起玩无济于事。这可能是正确的答案,但是点击此链接(Cython: How to expose void* and function pointer in struct?)似乎并不正确。