Act enthusiastic and you will be enthusiastic.
1.Cython 的由來(lái)
Python 是一門(mén)開(kāi)源免費(fèi)、語(yǔ)法簡(jiǎn)單的語(yǔ)言,然而解釋性語(yǔ)言的通病就是“運(yùn)行速度慢”,它遠(yuǎn)慢于 C/C++。為了解決該問(wèn)題,Python 官網(wǎng)提供了「Python/C API」,可以實(shí)現(xiàn)用 C 語(yǔ)言編寫(xiě) Python 庫(kù),即通過(guò) C 語(yǔ)言來(lái)編寫(xiě)部分核心邏輯來(lái)提高整體性能。然而,「Python/C API」門(mén)檻太高,于是誕生了 Cython。
只需編寫(xiě)簡(jiǎn)單的 Cython(語(yǔ)法與 Python 基本一致)代碼,就可以實(shí)現(xiàn) C 擴(kuò)展,如下圖所示:

2.什么是 Cython ?
「Cython」 是一個(gè)針對(duì) Python 語(yǔ)言和擴(kuò)展的 Cython 語(yǔ)言(基于 Pyrex)的優(yōu)化的靜態(tài)編譯器,即可將 Python/Cython 編譯成 C。它使得為 Python 編寫(xiě) C 擴(kuò)展就像 Python 本身一樣簡(jiǎn)單,優(yōu)點(diǎn)包括:
- 1)既具備了 Python 快速開(kāi)發(fā)的特點(diǎn),
- 2)又可以讓代碼運(yùn)行起來(lái)像 C 一樣快,
- 3)同時(shí)還可以方便地調(diào)用 C library。
在計(jì)算科學(xué)中,常用 Cython 來(lái)加速 Python 代碼。
3.安裝 Cython
3.1)配置 gcc
Cython 需要一個(gè) C 編譯器,不同平臺(tái)的安裝配置:
- windows
首先,安裝 MingW-w64 編譯器,命令:conda install libpython m2w64-toolchain -c msys2
然后,在 Python 安裝路徑下的 /Lib/distutils 下創(chuàng)建 distutils.cfg,并寫(xiě)入如下內(nèi)容:
[build] compiler=mingw32 - macOS
安裝 XCode 即可。 - linux:
gcc 一般都是配置好的,如果沒(méi)有可執(zhí)行命令:sudo apt-get install build-essential
3.2)安裝 Cython 庫(kù)
命令:pip install cython
Anaconda 環(huán)境下安裝命令:conda install cython
查看版本:cython --version
4.簡(jiǎn)單示例
1)定義要加速的模塊。
原始 Python 文件 multiply_python.py:
from time import time
# 自定義"計(jì)時(shí)"裝飾器
def cal_time(func):
def cal_time_wrapper(*args):
start_time = time()
result = func(*args)
end_time = time()
print("Python 耗時(shí)(秒):", end_time - start_time)
return result
return cal_time_wrapper
# 添加"計(jì)時(shí)"裝飾器
@cal_time
def my_multiply(a, b):
return a * b
需要加速的 Cython/Python 模塊 multiply_cython.pyx:
from time import time
# 自定義"計(jì)時(shí)"裝飾器
def cal_time(func):
def cal_time_wrapper(*args):
start_time = time()
result = func(*args)
end_time = time()
print("Cython 耗時(shí)(秒):", end_time - start_time)
return result
return cal_time_wrapper
# 添加"計(jì)時(shí)"裝飾器
@cal_time
def my_multiply(a, b):
return a * b
2)編寫(xiě) setup.py(名字不限) 文件——指定擴(kuò)展模塊,內(nèi)容如下:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules = [Extension("multiply_cython", ["multiply_cython.pyx"])]
setup(
name='multiply_demo',
cmdclass={'build_ext': build_ext},
ext_modules=ext_modules
)
3)執(zhí)行命令生成 C 擴(kuò)展:python setup.py build_ext --inplace。
執(zhí)行成功,生成一個(gè) .c 和一個(gè) .so 文件:

4)編寫(xiě) test.py 進(jìn)行測(cè)試,內(nèi)容如下:
import numpy as np
import multiply_python
import multiply_cython
x = np.arange(1, 25).reshape(2, 3, 4)
y = np.arange(10, 34).reshape(2, 3, 4)
multiply_python.my_multiply(x, y)
multiply_cython.my_multiply(x, y)
本例中,Cython 加速后的速度是原來(lái)的4.75倍,運(yùn)行結(jié)果如下:
Python 耗時(shí)(秒): 9.059906005859375e-06
('Cython 耗時(shí)(秒):', 1.9073486328125e-06)