我想使用类型化的memoryview来优化函数,但我不知道参数类型是什么。它可能是一个numpy数组甚至是一个标量。那么我应该如何使用typed memoryview?
答案 0 :(得分:1)
这类问题的问题在于动态键入Python,因此在选择要采用的代码路径时,您总是会失去速度。但是,原则上您可以非常快速地创建单独的代码路径。可能会给你带来好结果的方法是:
接下来是快速实施。这假定您希望将一个函数应用于输入数组的每个元素(并希望输出数组具有相同的大小)。我选择的说明函数只是为每个值加1。它也使用了numpy(我认为合理的地方(而不仅仅是键入的内存视图):
cimport cython
import numpy as np
import numbers
@cython.boundscheck(False)
cdef double[:] _plus_one_impl(double[:] x):
cdef int n
cdef double[:] output
output = x.copy()
for n in range(x.shape[0]):
output[n] = x[n]+1
return output
def plus_one(x):
if isinstance(x,numbers.Real): # check if it's a number
return _plus_one_impl(np.array([x]))[0]
else:
try:
return _plus_one_impl(x)
except ValueError: # this gets thrown if conversion fails
if len(x.shape)<2:
raise ValueError('x could not be converted to double [:]')
output = np.empty_like(x) # output is all numpy, whatever the input is
for n in range(x.shape[0]): # this loop isn't typed, so is likely to be pretty slow
output[n,...] = plus_one(x[n,...])
return output
在某些情况下(即具有短二维的2D数组),此代码可能会稍微缓慢。
然而,我真正的建议是研究numpy ufuncs,它提供了一个有效实现此类事情的接口。 (见http://docs.scipy.org/doc/numpy-dev/user/c-info.ufunc-tutorial.html)。不幸的是,它们比Cython更复杂。