python代碼加速運行的四種方法詳解
1.python執(zhí)行原理
python執(zhí)行過程:python腳本語言(.py)或者cython語言(.pyx)–解釋器解釋–>字節(jié)碼(.pyc)–虛擬機執(zhí)行–>機器碼(看不到,可以在cpu上跑起來)。
由于沒有原生的編譯時類型檢查,所有的類型的檢查都被移交給了運行時,執(zhí)行一行Python代碼很可能需要做不只一行的類型檢查、邊界檢查,因此python比起C++等會慢很多。
python的解釋器可以多種,常見的是cpython(最常用)、Ipython(基于cpython的交互式解釋器)、pypy(動圖編譯python代碼,運行速度快,與cpython有少數(shù)不同)、Jython、IronPython。
2.Cypthon(推薦,速度與numba接近)
Cython是一門語言,文件名以.pyx結(jié)尾。其是python的超集,即兼容python,Cython與python類似于C++與C的關(guān)系。同時Cython也是一個編譯器的名稱,其可將Cython語言寫的pyx文件(包含.py文件)直接編譯成動態(tài)庫,從而獲得近乎于寫CXX語言的性能。
官網(wǎng)推薦使用setuptools (setup.py)的方法來編譯.pyx/.py代碼。如以下文件樹,
├── os
│ └── ros_os.py
│ └── setup.py
目標是將os文件夾下的ros_os.py編譯成.so動態(tài)庫,因此在ros_os.py同級目錄下新建一個setup.py文件。setup.py的內(nèi)容如下:
from setuptools import setup from Cython.Build import cythonizesetup( name='ros_os', ext_modules=cythonize("ros_os.py"), zip_safe=False, )
然后運行指令python setup.py build_ext --inplace,則會在同級目錄下生成ros_os.so動態(tài)庫文件。在其他python文件中,就可以通過import導(dǎo)入該.so文件,實現(xiàn)加速。
注意,若os文件夾下有__init__.py文件,則會出錯。解決方法是需要將setup.py移動到與ros_os.py最近的無__init__.py文件的文件夾下,如以下文件樹所示:
├── pkg
│ ├── init.py
│ ├── os
│ │ ├── init.py
│ │ └── ros_os.py
└── setup.py
os文件夾下有__init__.py文件,顯式地表示os是一個python的包,同樣地,pkg下也存在__init__.py文件,因此需要將setup.py放在與pkg同級的目錄下,該目錄是最靠近ros_os.py的最近的且無__init__.py文件的目錄。同時,修改setup.py中對ros_os.py的路徑,如下:
from setuptools import setup from Cython.Build import cythonize setup( name='ros_os', ext_modules=cythonize("pkg/os/ros_os.py"), zip_safe=False, )
在setup.py的同級目錄下運行編譯指令:python setup.py build_ext --inplace,則可以正確編譯獲得ros_os.so動態(tài)文件。
優(yōu)點:加速python,并達到python加密的效果(推薦的加密手段)
缺點:需要手動編譯;少數(shù)python內(nèi)置屬性不支持,例如__file__;
3.numba(傳言可加速40倍左右)
numba是一個可以加速python大部分模塊的庫,其原理是將其修飾的函數(shù)在第一次運行時先優(yōu)化并翻譯成機器碼,而在重復(fù)運行時,則直接調(diào)用該機器碼,因此達到可以媲美C和C++的速度。使用方法如下:
from numba import jit # 從numba中導(dǎo)入函數(shù)jit import random @jit(nopython=True) # jit,numba裝飾器中的一種 def monte_carlo_pi(nsamples): acc = 0 for i in range(nsamples): x = random.random() y = random.random() if (x ** 2 + y ** 2) < 1.0: acc += 1 return 4.0 * acc / nsamples
在原始代碼中加入第1行和第4行,則可以加速monte_carlo_pi模塊(自動將其優(yōu)化并編譯成機器碼)。即,要加速哪個函數(shù),就在函數(shù)定義前面加上裝飾器@jit(nopython=True)。
優(yōu)點:對numpy和循環(huán)語法的加速明顯;使用方便;
缺點:少量庫無法加速,如pandas庫;僅能安裝到無法用于python2及以下版本;安裝比較困難,需要裝llvm編譯器;
4.其他加速方法
使用整型代替浮點型
5.各自加速方法的對比
代碼片段對大小為128x128的二維數(shù)組求和,運行1000次時間如下:
Total cost time for func: py_func, call 1000 times: 3.803216s.
Total cost time for func: np_func, call 1000 times: 0.343562s.
Total cost time for func: nb_func, call 1000 times: 0.017122s.
Total cost time for func: cy_func, call 1000 times: 0.018159s.
它們分別代表了原始Python、Numpy、Numba、Cython對應(yīng)的性能??梢钥闯?,cython與numba可有效加速python代碼。其中,numba以稍微快于cython,但是numba不兼容python2,且調(diào)試困難,因此,推薦使用cython。
6.方法補充
下面小編為大家整理了一些其他Python可以加速運行的技巧,希望對大家有所幫助
1.全面加速(pypy)
將python換為pypy,在純python代碼下,pypy的兼容性就不影響使用了,因為一些純python的代碼常常會用pypy進行一下加速
測試代碼,for循環(huán)10000000次
start = time.time() for i in range(10000000): print(i,end="\r") end = time.time() print(f"耗費時間{end-start}秒>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
2.if判斷靠前
如:
if tag in ["nts", "nto", "ntc", "ntcb", "ntcf", "ntch", "nth", "ntu", "nt"]: BMES(f_,i2, tag="ORG") elif tag in ["nb", "nba", "nbc", "nbp", "nf", "nm", "nmc", "nhm", "nh"]: BMES(f_,i2, tag="OBJ") elif tag in ["nnd", "nnt", "nn"]: BMES(f_,i2, tag="JOB") elif tag in ["nr", "nrf"]: BMES(f_,i2, tag="PER") elif tag in ["t"]: BMES(f_,i2, tag="TIME") elif tag in ["ns", "nsf"]: BMES(f_,i2, tag="LOC") else: for i3 in list(i2): f_.write(i3 + " " + f"O" + "\n")
滿足條件的可以先跳出判斷
到此這篇關(guān)于python代碼加速運行的四種方法詳解的文章就介紹到這了,更多相關(guān)python加速運行內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python光學(xué)仿真相速度和群速度計算理解學(xué)習(xí)
從物理學(xué)的機制出發(fā),波動模型相對于光線模型,顯然更加接近光的本質(zhì);但是從物理學(xué)的發(fā)展來說,波動光學(xué)旨在解決幾何光學(xué)無法解決的問題,可謂光線模型的一種升級2021-10-10python3實現(xiàn)raspberry pi(樹莓派)4驅(qū)小車控制程序
這篇文章主要為大家詳細介紹了python3實現(xiàn)raspberry pi(樹莓派)4驅(qū)小車控制程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-02-02使用beaker讓Facebook的Bottle框架支持session功能
這篇文章主要介紹了使用beaker讓Facebook的Bottle框架支持session功能,session在Python的Django等框架中內(nèi)置但在Bottle中并沒有被集成,需要的朋友可以參考下2015-04-04