直接用 cythonize 会失败是因为它仅将 .pyx 翻译为 .c 文件,不调用 c 编译器生成 .so/.pyd 扩展模块;正确做法是通过 setup.py 调用 python setup.py build_ext --inplace 完整构建。

为什么直接用 cythonize 会失败?
很多人跑完 cythonize -i module.pyx 就以为完事了,结果 import 时报 ImportError: No module named 'module'。根本原因是 Cython 编译后生成的是 .c 文件,但没触发 C 编译器(gcc/clang)真正生成 .so/.pyd——cythonize 默认只做翻译,不构建扩展模块。
正确做法是写 setup.py,用 setuptools 驱动完整构建流程:
from setuptools import setup
from Cython.Build import cythonize
<p>setup(
ext_modules = cythonize("module.pyx", compiler_directives={'language_level': 3})
)</p>
然后执行:python setup.py build_ext --inplace。注意:必须加 --inplace,否则编译产物在 build/ 目录里,import 找不到。
def 和 cdef 函数怎么选?
加速效果差异极大。Python 函数(def)只是把解释器调用换成 C 调用,仍走 Python 对象系统;cdef 函数完全脱离 Python 解释器,只能被同为 Cython 的代码调用,且参数/返回值必须声明 C 类型。
典型提速场景:
- 循环内部密集计算 → 用
cdef int i+cdef double x声明变量,避免 Python 对象创建开销 - 需要被 Python 层调用的入口函数 → 必须用
def或cpdef(后者生成 Python 和 C 两套接口) - 调用 C 标准库或 NumPy C API → 只能用
cdef,因为def无法传入裸指针
示例:一个纯计算函数,用 cdef 后比原生 Python 快 10–50 倍:
cdef int fast_sum(int n):
cdef int i, s = 0
for i in range(n):
s += i * i
return s
NumPy 数组怎么零拷贝传入 Cython?
直接传 np.array 给 def 函数仍是 Python 对象,Cython 会把它当普通对象处理,毫无加速效果。必须用内存视图(memoryview)或 np.ndarray 的 typed memoryview 语法。
关键点:
- 声明形参用
double[:] arr(一维)或double[:, :] mat(二维),不是np.ndarray - 调用前确保数组是 C-contiguous(
arr = np.ascontiguousarray(arr)),否则运行时报ValueError: Buffer has wrong number of dimensions - 避免在 Cython 里调用
arr.shape等 Python 属性——改用arr.shape[0],Cython 会自动转成 C 数组长度访问
错误写法:def process(np.ndarray arr): → 依然慢;正确写法:def process(double[:] arr):
如何确认加速真的生效了?
别只看总耗时下降——可能只是碰巧缓存命中或 GIL 没争抢。真实瓶颈是否被解决,得看三件事:
- 用
cython -a module.pyx生成 HTML 报告,黄色越少越好;深黄色行说明还在调用 Python C API,比如range()、len()、属性访问 - 用
perf record -e cycles,instructions python -c "import module; module.hot_func()"看 CPU 指令数是否显著下降 - 多线程场景下,确认函数是否真正释放 GIL:
cdef extern from "Python.h": void PyGILState_Release(void*)不必要,只要函数里没 Python 对象操作,Cython 默认就释放 GIL
最常被忽略的一点:Cython 加速只对 CPU-bound 有效。如果瓶颈在磁盘 IO、网络等待或 Python 层逻辑跳转(比如大量 if/else 判断),编译成 C 也救不了。先用 cProfile 定位 hot spot,再决定要不要上 Cython。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











