Cython 入門(mén)

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)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容