← 返回 Day 59 正文

Day 59 · 图解

Day 059 — C 扩展与性能优化 · 图解

性能优化路线图

                    ┌─────────────────┐
                    │  Python 代码慢   │
                    └────────┬────────┘
                             │
                    ┌────────▼────────┐
                    │  能用 NumPy?    │
                    └───┬─────────┬───┘
                   是   │         │  否
              ┌────────▼───┐  ┌──▼────────────┐
              │ NumPy 向量化│  │ 需要 JIT 编译?│
              │ (最省事)    │  └──┬─────────┬──┘
              └────────────┘ 是   │         │ 否
                   ┌────────▼───┐  │  ┌──────▼──────┐
                   │   Numba    │  │  │ 有 C 代码?  │
                   │ (装饰器)   │  │  └──┬───────┬──┘
                   └────────────┘  │  是  │       │ 否
                                  │ ┌────▼───┐ ┌─▼──────────┐
                                  │ │ctypes/ │ │  Cython     │
                                  │ │CFFI    │ │ (写 C 扩展) │
                                  │ └────────┘ └─────────────┘
                                  └──────────────┘

Cython 编译流程

 .pyx 文件          Cython 编译器          gcc/clang           .so/.pyd
(Python+C语法)  ─────────────────→  (.c 文件)  ──────────→  (共享库)
                                        │
                                   生成 C 代码
                                   做类型优化

ctypes / CFFI 调用流程

Python 代码        ctypes/CFFI          C 共享库          系统调用
     │               │                    │                 │
     │  创建参数      │  类型转换           │  执行 C 函数     │
     ├──────────────→├──────────────────→├────────────────→│
     │               │                    │                  │
     │  返回结果      │  类型转换回 Python  │  返回 C 值       │
     │←──────────────│←──────────────────│←─────────────────│

Numba JIT 编译流程

Python 函数          @jit 装饰器         LLVM 编译器          机器码
   │                    │                   │                  │
   │  首次调用           │  分析函数         │  生成 LLVM IR     │
   ├───────────────────→├────────────────→├─────────────────→│
   │                    │                   │                  │
   │                    │                   │  编译为原生代码    │
   │                    │                   ├─────────────────→│
   │                    │                   │                  │
   │  后续调用           │  直接执行          │                  │
   │←────────────────────────────────────────────────────────│

方案对比雷达图

         安装难度
            ▲
            │
     5 ─────┼─────
            │
   学习     │     性能
   曲线 ◄───┼───► 加速比
            │
     5 ─────┼─────
            │
            ▼
        适用范围

  ── Numba (性能最高,学习最低)
  ── Cython (范围最广,学习最高)
  ── ctypes (安装最低,性能中等)
  ── CFFI (比 ctypes 更现代)