【Python】透過Cython提升效能

changwan發表於2024-07-18

一、什麼是Cython,

如果你瞭解Python,就會知道Python相比於其他語言,效能差了不是一點半點。但是Python的底層實現大量使用了C語言,可以與C語言很好的結合。並且在Python中由於GIL全域性直譯器鎖的機制,導致python在實現CPU密集型操作時非常吃力。Cython是Python的一個擴充套件,用於將Python程式碼編譯為C程式碼,並且可以完美的避開GIL機制,,從而顯著提升效能。

二、呼叫.C檔案

1、安裝cython

pip install cython

2、編寫.h標頭檔案和.c檔案

int sub(int n);//sub.h

編寫C語言檔案sub.c

#include "sub.h"

int sub(int n) {
    return n*(n+1)/2;
}

3、編寫sub.pyx檔案

cdef extern from "sub.h":
    int sub(int n)

def sub_with_c(n):
    return sub(n) 

4、編寫setup.py檔案

from distutils.core import setup,Extension
from Cython.Build import cythonize

ext = Extension(name="wrapper_sub",sources=["sub.pyx","c/sub.c"],language_level=3,)  
setup(ext_modules=cythonize(ext)) 

5、執行setup.py檔案

python setup.py build

會生成一個sub.c檔案和build目錄以及wrapper_sub.cpython-39-darwin.so檔案就是我們需要的共享模組。其餘的可以刪除。

6、呼叫共享模組

import wrapper_sub

if __name__ == '__main__':
    print(wrapper_sub.sub_with_c(100))

透過呼叫C編譯後的檔案可以極大的提高執行速度,並且可以避免GIL全域性直譯器鎖的影響。

三、將Python程式碼編譯為C共享模組

1、編寫ArrarySort.pyx檔案

這裡實際上就是編寫Python程式碼,將py字尾改為pyx

def arr_list(arr:list):
    arr.sort()
    return arr

2、編寫setup.py指令碼

from distutils.core import setup
from Cython.Build import cythonize

setup(ext_modules=cythonize("ArrarySort.pyx",language=3))

3、執行setup指令碼

python setup.py build_ext --inplace

生成ArrarySort.cpython-39-darwin.so檔案,其餘檔案可以刪除。

4、呼叫共享模組

import ArrarySort

a= ArrarySort.arr_list([12,2134,2345,12,2])
print(a)

四、手動編寫Cython

Cython本身有一套自己的寫法規則,類似Python和C語言。可以直接編寫pyx檔案,將pyx編譯為C程式碼,gcc編譯器編譯為共享模組(這一步可以不需要手動操作,distutils 自動處理)。

手動操作的話指令

gcc -shared -fPIC -I/python3.9 -o bubble_sort.so bubble_sort.c

1、編寫pyx檔案

這裡使用Cython自身的語法規則,不需要使用C或Python進行其他的操作

def bubble_sort(arr):
    cdef int n = len(arr)
    cdef int i, j
    cdef int temp
    for i in range(n):
        for j in range(0, n-i-1):
            if arr[j] > arr[j+1]:
                temp = arr[j]
                arr[j] = arr[j+1]
                arr[j+1] = temp

2、編寫setup.py指令碼

from distutils.core import setup
from Cython.Build import cythonize

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

3、執行setup.py指令碼

python setup.py build_ext --inplace

會在當前目錄中生成一個與 bubble_sort 相對應的 C 檔案,並編譯生成一個共享物件檔案(在 Linux 上是 .so 檔案,在 Windows 上是 .pyd 檔案)。這時候我們只需要共享檔案即可。

4、在Python中呼叫共享模組

import arrary_sort

arr = [1,3,2,4,3,5,6,2,6,7,3]
arrary_sort.bubble_sort(arr)
print(arr)

五、總結

Cython是一種工具,可以讓Python程式跑得更快。它透過將Python程式碼轉換成C語言程式碼並進行編譯,大大提升了程式的執行效率。使用Cython,你可以在Python程式碼中直接書寫C語言的型別宣告,這樣不僅減少了直譯器的開銷,還能更高效地執行計算密集型任務。此外,Cython還能直接呼叫C語言的函式和資料型別,使得Python程式可以利用C語言的高效能。這種方法特別適合需要處理大量計算任務的場景,比如科學計算、資料分析和機器學習。同時,Cython保留了Python的簡潔易用,開發者可以逐步最佳化程式碼,不需要一次性重寫整個專案。這樣,既能享受Python的開發便利,又能獲得接近C語言的執行效率。

相關文章