Cython语言基础
本章介绍Cython核心语法,掌握后能编写高效编译代码。Cython是Python超集,语法向下兼容,但通过cdef、cpdef等关键字可引入静态类型声明,编译后获得C级性能。
学习路径:语法基础 → 变量声明 → 函数定义 → 控制流 → 运算符
核心区别:
def:Python可调用,灵活但慢cdef:C级调用,性能最高,但Python不可直接调用cpdef:双重调用,兼顾易用与性能
2.1 .pyx文件语法
Section titled “2.1 .pyx文件语法”与Python语法对比
Section titled “与Python语法对比”Cython是Python超集,标准Python代码直接兼容:
# 标准Python代码在Cython中完全兼容import math
def python_style_list(): result = [] for i in range(10): result.append(i ** 2) return result说明:纯Python代码不享受静态类型优化,但可逐步添加Cython特性。
Python兼容模式
Section titled “Python兼容模式”两种风格对比——纯Python vs Cython优化:
# 纯Python风格 - 无类型声明,编译为纯Python字节码def pure_python(): return [x for x in range(100)]
# Cython优化 - 静态类型声明cpdef list cython_style(int n): cdef int i cdef list result = [] for i in range(n): result.append(i * i) return result性能差异:cython_style比pure_python快约50-100倍(n=10000时)。
静态类型声明语法(cdef)
Section titled “静态类型声明语法(cdef)”cdef用于声明变量和函数静态类型:
# cdef用于声明变量和函数的静态类型cdef int count = 0cdef double pi = 3.14159cdef str name = "Cython"常见坑:未声明类型的变量会退化为Python对象,失去C级性能。
2.2 变量声明
Section titled “2.2 变量声明”功能:声明C语言原生类型,获得最高运行效率。
# 整数类型cdef int i = 10 # 标准32位整数cdef long j = 1000000 # 长整数(平台相关)cdef long long k = 10000000000 # 64位整数cdef short s = 5 # 16位整数
# 无符号整数cdef unsigned int ui = 100cdef unsigned long ul = 1000000
# 浮点类型cdef float f = 3.14 # 32位浮点cdef double d = 2.718281828 # 64位浮点cdef long double ld = 1.414213562 # 高精度浮点
# 字符cdef char c = 'A'选择建议:一般情况用int、double,大数值用long long,避免short除非内存敏感。
Python对象类型
Section titled “Python对象类型”功能:声明Python对象类型,保持与Python运行时兼容。
# object类型 - 通用Python对象容器cdef object objcdef list lstcdef dict dctcdef str s
# 强类型声明 - 指定具体Python类型cdef list numberscdef dict mappingscdef str textcdef int value # Python整数对象说明:cdef int value声明的是Python整数对象,不是C整数。两者性能差异约10倍。
类型转换规则
Section titled “类型转换规则”功能:展示不同类型间的转换行为。
# C级类型隐式转换(安全,自动转换)cdef int a = 5cdef double b = a # int → double 自动转换,结果 b = 5.0
# Python对象转换cdef list lst = list(range(10)) # 从range对象转换cdef str s = str(123) # 整数转字符串,结果 "123"
# 显式类型转换(C风格)cdef double d = <double>a # 强制转换,结果 5.0最佳实践:
- 避免混合C类型和Python对象计算
- 高精度转低精度时使用显式转换,避免警告
2.3 函数定义
Section titled “2.3 函数定义”def函数:Python可调用
Section titled “def函数:Python可调用”功能:定义可从Python调用的函数,但无静态类型优化。
# def函数 - 可被Python调用,返回Python对象def sum_py(n): """纯Python函数,性能较低""" total = 0 for i in range(n): total += i return total输出示例:
>>> sum_py(100)4950cdef函数:C级别高性能
Section titled “cdef函数:C级别高性能”功能:定义C级函数,性能极高,但只能被Cython代码调用。
# cdef函数 - 只能被Cython代码调用,无法从Python直接调用cdef int sum_c(int n): """C级函数,性能极高""" cdef int total = 0 cdef int i for i in range(n): total += i return total调用方式:需通过cpdef包装或从其他.pyx文件调用。
cpdef函数:双重可调用
Section titled “cpdef函数:双重可调用”功能:兼顾Python调用和C级性能,推荐优先使用。
# cpdef函数 - 可被Python和Cython调用cpdef int sum_cp(int n): """双重可调用函数""" cdef int total = 0 cdef int i for i in range(n): total += i return total输出示例:
>>> sum_cp(100)4950性能对比(n=10000000):
| 函数类型 | 耗时 |
|---|---|
sum_py | ~800ms |
sum_cp | ~10ms |
sum_c | ~8ms |
函数参数类型声明
Section titled “函数参数类型声明”功能:展示参数类型声明的不同写法。
# 仅有类型声明(参数类型自动推导)cpdef double average(list values): cdef double total = 0.0 cdef int i for i in range(len(values)): total += values[i] return total / len(values)
# 带默认值参数cpdef void process(int n, str mode="normal"): cdef int i for i in range(n): if mode == "verbose": print(i)最佳实践:
cpdef函数参数避免使用C类型(Python调用时需转换)- 默认值必须是Python对象类型,不能是C字面量
2.4 控制流
Section titled “2.4 控制流”功能:if-elif-else结构,与Python语法相同。
# if-elif-else条件判断cdef char classify(int score): if score >= 90: return 'A' elif score >= 80: return 'B' elif score >= 70: return 'C' else: return 'D'输出示例:
>>> classify(85)'B'优化说明:可省略最后else分支,直接返回默认值,减少缩进层级。
功能:while和for循环的Cython优化写法。
# while循环 - 适合条件不确定的场景cdef int countdown(int n): cdef int i = n while i > 0: i -= 1 return i
# for循环 - 适合已知迭代次数cdef int sum_range(int n): cdef int total = 0 cdef int i for i in range(n): total += i return total
# 反向遍历cdef int sum_reverse(int n): cdef int total = 0 cdef int i for i in range(n - 1, -1, -1): total += i return total输出示例:
>>> sum_range(5)10 # 0+1+2+3+4
>>> sum_reverse(5)10 # 4+3+2+1+0循环选择指南
Section titled “循环选择指南”功能:根据场景选择合适的循环类型。
# 场景1:C级索引遍历typed memoryviewcdef double sum_array(double[:] arr): cdef int total = 0.0 cdef int i cdef double val for i in range(len(arr)): val = arr[i] total += val return total
# 场景2:需要无限循环能力(如等待标志位)cdef void wait_for_flag(bint *flag): cdef int count = 0 while not flag[0]: count += 1 if count > 1000000: break常见坑:
for i in arr会退化为Python迭代,失去C级性能- 使用
range(len(arr))而非arr直接遍历
2.5 运算符与表达式
Section titled “2.5 运算符与表达式”功能:C风格算术运算,整数除法行为与C相同。
# 算术运算符cdef int a = 10, b = 3cdef int result_intcdef double result_float
result_int = a + b # 加法: 13result_int = a - b # 减法: 7result_int = a * b # 乘法: 30result_int = a / b # 整数除法: 3(C风格)result_int = a % b # 取模: 1
# 浮点除法result_float = <double>a / b # 3.333...(需显式转换)输出示例:
>>> a / b3 # Python3返回float 3.333...>>> <int>a / b # C风格整数除法3功能:直接操作二进制位,常用于性能优化(乘除2的快速算法)。
cdef int x = 0b1100 # 12cdef int y = 0b1010 # 10
# 位运算cdef int and_result = x & y # 0b1000 = 8cdef int or_result = x | y # 0b1110 = 14cdef int xor_result = x ^ y # 0b0110 = 6cdef int not_result = ~x # -13(补码表示)cdef int left_shift = x << 2 # 48(乘4)cdef int right_shift = x >> 2 # 3(除4,向下取整)输出示例:
>>> x << 248 # 12 * 4 = 48
>>> x >> 23 # 12 / 4 = 3(整数除法)最佳实践:位运算比乘除快约3-5倍,大规模数值计算时效果显著。
功能:C优先级规则,避免运算符优先级错误。
# C优先级:() > [] > * / % > + - > << >> > < <= > >=# > & > ^ > | > && > || > = += -= *= /= %=
cdef int a = 1, b = 2, c = 3cdef int result
result = a + b * c # 1 + (2 * 3) = 7result = (a + b) * c # (1 + 2) * 3 = 9result = a | b & c # 1 | (2 & 3) = 3result = (a | b) & c # (1 | 2) & 3 = 3常见坑:位运算优先级低于比较运算符,a | b & c按a | (b & c)计算而非(a | b) & c。
功能:合并运算与赋值的简写形式。
cdef int x = 10
x += 5 # x = 15x -= 3 # x = 12x *= 2 # x = 24x /= 4 # x = 6(整数除法)x %= 5 # x = 1
# 位运算复合赋值x <<= 2 # x = 4(左移2位)x >>= 1 # x = 2(右移1位)x &= 0b11 # x = 0(按位与)优化建议:复合赋值比单独运算稍快,适用于循环内高频操作。
| Python | Cython | 说明 | 性能 |
|---|---|---|---|
def func(x): | def func(x): | Python可调用 | 慢 |
| 无 | cdef int func(int x): | C可调用 | 最快 |
| 无 | cpdef int func(int x): | 双重可调用 | 快 |
x = 10 | cdef int x = 10 | 静态类型声明 | - |
for i in range(n): | for i in range(n): | 静态类型时C级性能 | 差异大 |
while cond: | `while cond:“ | 相同语法 | - |
关键要点:
cdef声明的类型获得C级性能cpdef是最实用的函数定义方式- 避免Python对象与C类型混合计算
- 位运算比乘除快,用于性能敏感场景
- 创建包含
def、cdef、cpdef函数的.pyx文件,对比调用方式差异 - 实现一个计算typed memoryview元素和的函数,对比与普通list的性能
- 用位运算实现整数乘除2的快速算法(
x << 1=x * 2) - 比较
while循环和for循环在Cython中的性能差异 - 编写一个同时使用C类型(
int、double)和Python对象(list、dict)的函数