← 返回首页
编译

Cython入门

📂 python ⏱ 2 min 386 words

Cython入门

Cython是Python的超集,允许添加静态类型声明并编译为C代码,显著提升性能。本文将介绍Cython的核心概念和优化技巧。

基本语法

Cython使用.pyx扩展名,语法类似Python但可添加类型:

# example.pyx
def calculate_sum(int n):
    cdef int i, total = 0
    for i in range(n):
        total += i
    return total

类型声明

# 静态类型变量
cdef int x = 10
cdef double pi = 3.14159
cdef list py_list = [1, 2, 3]
cdef dict py_dict = {"key": "value"}

# 函数参数类型
def process_array(double[:] arr):
    cdef int i
    cdef double total = 0
    for i in range(arr.shape[0]):
        total += arr[i]
    return total

# 返回类型声明
cpdef int fast_add(int a, int b):
    return a + b

编译配置

创建setup.py编译Cython代码:

from setuptools import setup
from Cython.Build import cythonize

setup(
    ext_modules=cythonize("example.pyx")
)

编译命令:

python setup.py build_ext --inplace

性能优化技巧

使用NumPy数组

import numpy as np
cimport numpy as np

def matrix_multiply(double[:, :] a, double[:, :] b):
    cdef int i, j, k
    cdef int m = a.shape[0]
    cdef int n = a.shape[1]
    cdef int p = b.shape[1]
    
    result = np.zeros((m, p), dtype=np.float64)
    cdef double[:, :] res_view = result
    
    for i in range(m):
        for j in range(p):
            for k in range(n):
                res_view[i, j] += a[i, k] * b[k, j]
    
    return result

并行处理

from cython.parallel import prange

def parallel_sum(double[:] arr):
    cdef int i
    cdef double total = 0
    
    for i in prange(arr.shape[0], nogil=True):
        total += arr[i]
    
    return total

与Python互操作

# cdef函数:纯C函数,Python不可调用
cdef int internal_helper(int x):
    return x * 2

# cpdef函数:Python和C都可调用
cpdef int public_function(int x):
    return internal_helper(x)

# 调用Python对象
def process_with_python(list items):
    cdef int i
    result = []
    
    for i in range(len(items)):
        # 调用Python的len函数
        if i < len(items):
            result.append(items[i] * 2)
    
    return result

高级特性

条件编译

DEF DEBUG = True

def debug_function():
    IF DEBUG:
        print("调试信息")
    return 42

异常处理

def safe_divide(double a, double b):
    if b == 0:
        raise ValueError("除数不能为零")
    return a / b

C++集成

# distutils: language = c++
from libcpp.vector import vector

def cpp_vector_demo():
    cdef vector[int] vec
    vec.push_back(1)
    vec.push_back(2)
    return vec.size()

实际应用示例

# 图像处理加速
import numpy as np
cimport numpy as np

def grayscale_convert(uint8_t[:, :, :] rgb):
    cdef int h = rgb.shape[0]
    cdef int w = rgb.shape[1]
    cdef int i, j
    cdef uint8_t r, g, b
    
    result = np.zeros((h, w), dtype=np.uint8)
    cdef uint8_t[:, :] gray = result
    
    for i in range(h):
        for j in range(w):
            r = rgb[i, j, 0]
            g = rgb[i, j, 1]
            b = rgb[i, j, 2]
            gray[i, j] = <uint8_t>(0.299 * r + 0.587 * g + 0.114 * b)
    
    return result

调试技巧

  1. 使用cython -a生成HTML注解文件,查看Python交互程度
  2. 添加--gdb调试标志
  3. 使用print语句调试(Cython支持)
  4. 利用gdb调试生成的C代码

常见问题

总结

Cython是提升Python性能的强大工具。通过静态类型声明和编译优化,可以获得接近C的性能,同时保持Python的易用性。建议从简单的类型注解开始,逐步优化关键路径。