【python开发技术】Cython 开发学习
使用Cython来进行Python C/C++交互
可以通过Cython编写python脚本,生成.c文件以及对应的python 的c extension package,用于加速python执行速度。
python有些慢的原因主要是啥都是运行时决定,而不是像C/C++编译时就决定了。而Cython采用python的脚本.pyx
编写,通过cimport来引入.pxd
文件,用@cython.boundscheck(False)和@cython.wraparound(False)两个修饰关闭边界检查,用cdef定义函数,可以定义返回值类型:
cdef int min(int x, int y):
return x if x <=y else y
具体可以参考:
# 编写的cython .pyx文件
import numpy as np
cimport numpy as np
cimport cython
@cython.boundscheck(False)
@cython.wraparound(False)
cdef np.ndarray[np.float32_t, ndim=2] _naive_dot(np.ndarray[np.float32_t, ndim=2] a, np.ndarray[np.float32_t, ndim=2] b):
cdef np.ndarray[np.float32_t, ndim=2] c
cdef int n, p, m
cdef np.float32_t s
if a.shape[1] != b.shape[0]:
raise ValueError('shape not matched')
n, p, m = a.shape[0], a.shape[1], b.shape[1]
c = np.zeros((n, m), dtype=np.float32)
for i in range(n):
for j in range(m):
s = 0
for k in range(p):
s += a[i,k] * b[k,j]
c[i,j] = s
return c
def naive_dot(a, b):
return _naive_dot(a, b)
# 编写的setup.py文件
from distutils.core import setup, Extension
from Cython.Build import cythonize
import numpy
setup(ext_modules=cythonize(Extension(
'dot_cython',
sources=['dot_cython.pyx'],
language='c',
include_dirs=[numpy.get_include()],
libraries=[],
library_dirs=[],
extra_compile_args=[],
extra_link_args=[],
)))
调用命令:
python setup.py build_ext --inplace
会生成对应的dot_cython.cp36-win_amd64.pyd
和dot_cython.c
文件,即可实现调用。
对Cython程序进行分析
Cython的类型声明很重要,而不加类型声明也不会报错,会有可能漏加声明,Cython提供了工具进行分析:
cython -a dot_cython.pyx
而若当前Cython用到了C++,还需加上–cplus参数。
补充说明
Python 是很好的胶水语言,但是前提是库本身要使用 Python API 来和 Python 交互。有了 Cython 之后,我们可以照常编写 C/C++ 程序,或者是直接拿来一份已有的 C/C++ 源码,然后用 Cython 简单包装一下就可以使用了。
函数签名基本上可以原样从 C/C++ 复制到 Cython 中
C 中的 _Bool 类型和 C++ 中的 bool 类型在 Cython 中都用 bint 取代(因为 Python 没有布尔类型)
struct / enum / union 是支持的
const 限定和引用都是支持的
命名空间是支持的
C++ 类是支持的
部分操作符重载是支持的,部分操作符需要改名
内嵌类是支持的
模板是支持的
异常是支持的
构造函数、析构函数是支持的
静态成员是支持的
libc / libcpp / STL 是支持的
声明写在 .pxd 中可以在 .pyx 中 cimport 进来
你可能需要注意 Python 字符串到各式各样的 C/C++ 字符串的转换
- Using C++ in Cython
- Extension Types
- Special Methods of Extension Types
- Sharing Declarations Between Cython Modules
- Unicode and passing strings
- cython/Cython/Includes
- wrapping struct with nested enum - reference in vector template