如何使用C語言最佳化Python程式碼

Cython是Python程式語言的編譯器,旨在最佳化效能並形成擴充套件的Cython程式語言。作為Python的擴充套件,Cython也是Python語言的超集,它支援呼叫C函式,並在變數和類屬性上宣告C型別。這使得包裝外部C庫、將C嵌入現有應用程式或以Python的語法編寫C擴充套件變得像Python本身一樣簡單。

Cython通常用於建立加速Python程式碼執行的C模組。在解釋語言效率不高的複雜應用程式中,這一點很重要。

安裝Cython

可以使用Python在Linux、BSD、Windows或macOS上安裝Cython:

$ python -m pip install Cython

將Python轉換為C

從Cython開始的一個好方法是使用一個簡單的“Hello World ”應用程式。這不是優勢的最好證明,但它顯示了你使用時會發生什麼。

首先,在一個名為

hello.pyx

的檔案中建立這個簡單的Python指令碼(

.pyx

副檔名並不神奇,從技術上講,它可以是任何東西,但它是Cython的預設副檔名):

print("hello world")

接下來,建立一個Python安裝指令碼。  setup。py檔案類似於Makefile的Python版本,Cython可以使用它來處理Python程式碼:

from setuptools import setupfrom Cython.Build import cythonizesetup(    ext_modules = cythonize("hello.pyx"))

最後,使用Cython將Python指令碼轉換為C程式碼:

$ python setup.py build_ext --inplace

要使用Python“Hello World”指令碼的C程式碼版本,請開啟Python提示並匯入建立的新模組:

>>> import hellohello world

將C程式碼整合到Python中

計算能力的一個很好的通用測試是計算素數。素數是大於1的正數,只有在除以1或本身時才產生正整數。理論上很簡單,但隨著數字變大,計算要求也增加了。在純Python中,它可以在10行程式碼下完成:

import sysnumber = int(sys.argv[1])if not number <= 1:    for i in range(2, number):        if (number % i) == 0:            print("Not prime")            breakelse:    print("Integer must be greater than 1")

此指令碼在成功後將保持不變,如果數字不是素數,則返回一條訊息:

$ ./prime.py 3$ ./prime.py 4Not prime.

將其轉換為Cython需要進行一些工作,一方面使程式碼適合用作庫,另一方面使效能提高。

指令碼和庫

許多使用者將Python作為一種指令碼語言進行學習:把將要執行的步驟告訴Python,然後它就可以完成工作。 當了解更多有關Python(以及一般來說是開放原始碼程式設計)的知識時,會發現許多最強大的程式碼包含在其他應用程式可以利用的庫中。 程式碼越不具體,程式設計師將其重新用於其他應用程式的可能性就越大。

對於這個簡單的質數計算器,將其轉換為Cython的過程是透過設定指令碼開始的:

from setuptools import setupfrom Cython.Build import cythonizesetup(    ext_modules = cythonize("prime.py"))

將指令碼轉換為C:

$ python setup.py build_ext --inplace

到目前為止,一切似乎都執行良好,但是當嘗試匯入和使用新模組時,會出現錯誤:

>>> import primeTraceback (most recent call last):  File "<stdin>", line 1, in <module>  File "prime.py", line 2, in init prime    number = sys.argv[1]IndexError: list index out of range

問題在於,Python指令碼希望從終端執行,在終端上,引數(在這種情況下,是要測試為質數的整數)很常見。 需要修改指令碼,以便可以將其用作庫。

編寫一個庫

庫不使用系統引數,而是接受其他程式碼的引數。 不用使用sys。argv來引入使用者輸入,而是使程式碼成為一個接受稱為number(或num或喜歡的任何變數名)的引數的函式:

def calculate(number):    if not number <= 1:        for i in range(2, number):            if (number % i) == 0:                print("Not prime")                break    else:        print("Integer must be greater than 1")

這使指令碼難以測試,因為當在Python中執行程式碼時,永遠不會執行calculate函式。 但是,Python程式設計師針對此問題設計了一種通用的解決方法,即使不是直觀的方法。 當Python直譯器執行Python指令碼時,有一個名為__name__的特殊變數被設定為__main__,但是當它作為模組匯入時,__name__被設定為模組的名稱。 透過利用這一點,您可以編寫一個既是Python模組又是有效的Python指令碼的庫:

import sysdef calculate(number):    if not number <= 1:        for i in range(2, number):            if (number % i) == 0:                print("Not prime")                break    else:        print("Integer must be greater than 1")if __name__ == "__main__":    number = sys.argv[1]        calculate( int(number) )

現在,可以將程式碼作為命令執行:

$ python ./prime.py 4Not a prime

可以將其轉換為Cython以用作模組:

>>> import prime>>> prime.calculate(4)Not prime

C語言Python

使用Cython將程式碼從純Python轉換為C可能會很有用。 但是還有Cython功能可幫助使用者在轉換前最佳化程式碼,還可以選擇分析程式碼以查詢Cython與C互動的時間,等等。 如果使用的是Python,希望透過C程式碼增強程式碼,或者進一步瞭解庫如何提供比指令碼更好的可擴充套件性,或者只是對Python和C如何協同工作感到好奇,那麼請開始使用Cython。

好了,本文到此結束。如果對程式設計、計算機、程式設計師方面感興趣的話,歡迎私信聯絡我,隨時交流!點個關注,是對我莫大的鼓勵!

相關文章