我刚刚开始尝试使用cython,并且作为第一个练习,我创建了一个计算数组中每个元素的sin函数的下列(重新)实现。因此,这里是我的sin.pyx为什么Numpy的性能超过了这个例程的3
from numpy cimport ndarray, float64_t
import numpy as np
cdef extern from "math.h":
double sin(double x)
def sin_array(ndarray[float64_t, ndim=1] arr):
cdef int n = len(arr)
cdef ndarray h = np.zeros(n, dtype=np.float64)
for i in range(n):
h[i] = sin(arr[i])
return h
我也创建了以下setup.py此
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import numpy
ext = Extension("sin", sources=["sin.pyx"])
setup(ext_modules=[ext],
cmdclass={"build_ext": build_ext},
include_dirs=[numpy.get_include()])
所以这造成我的* .so文件。我将它导入python并创建1000个随机数,例如
import sin
import numpy as np
x = np.random.randn(1000)
%timeit sin.sin_array(x)
%timeit np.sin(x)
Numpy赢了3倍。为什么?我认为一个对输入数组的类型和维度做出非常明确的假设的函数可以在这里更具竞争力。当然,我也明白,numpy是不可思议的,但有可能是我在这里做一些愚蠢的事情......
请注意,这个练习的重点是不要重写更快的sin函数,而是要创建一些cython封皮为我们的一些内部工具,但这是以后的另一个问题...
在您的Cython代码中是否还存在边界检查?在[文档示例](http://docs.cython.org/src/userguide/numpy_tutorial.html#numpy-tutorial)中,他们在某个时候关闭了它。 – Evert 2014-10-07 08:52:49
是的,我现在已经包括了。只有很小的改进。仍然几乎因素3 ... – tschm 2014-10-07 09:03:45
http://stackoverflow.com/questions/14466950/why-is-my-python-numpy-example-faster-than-pure-c-implementation – tschm 2014-10-07 09:17:16