Python中Numba庫(kù)裝飾器的具體使用
一、運(yùn)行速度是Python天生的短板
1.1 編譯型語(yǔ)言:C++
對(duì)于編譯型語(yǔ)言,開(kāi)發(fā)完成以后需要將所有的源代碼都轉(zhuǎn)換成可執(zhí)行程序,比如 Windows 下的.exe文件,可執(zhí)行程序里面包含的就是機(jī)器碼。只要我們擁有可執(zhí)行程序,就可以隨時(shí)運(yùn)行,不用再重新編譯了,也就是“一次編譯,無(wú)限次運(yùn)行”。
在運(yùn)行的時(shí)候,我們只需要編譯生成的可執(zhí)行程序,不再需要源代碼和編譯器了,所以說(shuō)編譯型語(yǔ)言可以脫離開(kāi)發(fā)環(huán)境運(yùn)行。
編譯型語(yǔ)言一般是不能跨平臺(tái)的,也就是不能在不同的操作系統(tǒng)之間隨意切換。
1.2 解釋型語(yǔ)言:Python
對(duì)于解釋型語(yǔ)言,每次執(zhí)行程序都需要一邊轉(zhuǎn)換一邊執(zhí)行,用到哪些源代碼就將哪些源代碼轉(zhuǎn)換成機(jī)器碼,用不到的不進(jìn)行任何處理。每次執(zhí)行程序時(shí)可能使用不同的功能,這個(gè)時(shí)候需要轉(zhuǎn)換的源代碼也不一樣。
因?yàn)槊看螆?zhí)行程序都需要重新轉(zhuǎn)換源代碼,所以解釋型語(yǔ)言的執(zhí)行效率天生就低于編譯型語(yǔ)言,甚至存在數(shù)量級(jí)的差距。計(jì)算機(jī)的一些底層功能,或者關(guān)鍵算法,一般都使用 C/C++ 實(shí)現(xiàn),只有在應(yīng)用層面(比如網(wǎng)站開(kāi)發(fā)、批處理、小工具等)才會(huì)使用解釋型語(yǔ)言。
在運(yùn)行解釋型語(yǔ)言的時(shí)候,我們始終都需要源代碼和解釋器,所以說(shuō)它無(wú)法脫離開(kāi)發(fā)環(huán)境。
1.3 速度對(duì)比:C++比Python快25倍
我不會(huì)C++語(yǔ)言、也沒(méi)有C++語(yǔ)言的運(yùn)行的環(huán)境,借用網(wǎng)友的對(duì)比結(jié)果:
編譯后,運(yùn)行C++代碼,生成全部13-mers共6700萬(wàn)個(gè)大約需要2.42秒。這意味著運(yùn)行相同算法,Python用時(shí)是C++的25倍多。
二、Numba使用與否的對(duì)比,計(jì)算1000萬(wàn)以內(nèi)的素?cái)?shù)
2.1 原生Python,計(jì)算1000萬(wàn)以內(nèi)的素?cái)?shù)
def U27_1000W以內(nèi)的素?cái)?shù)(): import math import time def is_prime(num): if num == 2: return True if num <= 1 or num % 2 == 0: return False for div in range(3, int(math.sqrt(num) + 1), 2): if num % div == 0: return False return True def run_program(N): total = 0 for i in range(N): if is_prime(i): total += 1 return total # if __name__ == "__main__": N = 10000000 start = time.time() total = run_program(N) end = time.time() print(f"1000萬(wàn)以內(nèi)所有的素?cái)?shù)有 {total} 個(gè)") print(f"純Python耗時(shí): {end - start} 秒\b") return end - start
2.2 Numba裝飾器,計(jì)算1000萬(wàn)以內(nèi)的素?cái)?shù)
def U28_1000W以內(nèi)的素?cái)?shù)_Numba裝飾器(): import math import time from numba import njit, prange # @njit 相當(dāng)于 @jit(nopython=True) @njit def is_prime(num): if num == 2: # 2為素?cái)?shù) return True if num <= 1 or num % 2 == 0: # 偶數(shù)中除了2都不是素?cái)?shù) return False for div in range(3, int(math.sqrt(num) + 1), 2): if num % div == 0: return False return True #使用Numba的prange來(lái)進(jìn)行并發(fā)循環(huán)計(jì)算 @njit(parallel = True) def run_program(N): total = 0 #使用Numba提供的prange參數(shù)來(lái)進(jìn)行并行計(jì)算 for i in prange(N): if is_prime(i): total += 1 return total # if __name__ == "__main__": N = 10000000 start = time.time() total = run_program(N) end = time.time() print(f"1000萬(wàn)以內(nèi)所有的素?cái)?shù)有 {total} 個(gè)") print(f"Numba裝飾器耗時(shí): {end - start} 秒\b") return end - start
2.3 實(shí)測(cè)速度:使用numba裝飾器,速度提升 22.0 倍,逼近C++
t0 = U27_1000W以內(nèi)的素?cái)?shù)() t1 = U28_1000W以內(nèi)的素?cái)?shù)_Numba裝飾器() print(f'使用numba裝飾器,速度提升 {round(t0/t1, 0)} 倍') 1000萬(wàn)以內(nèi)所有的素?cái)?shù)有 664579 個(gè) 純Python耗時(shí): 86.78110885620117 秒 1000萬(wàn)以內(nèi)所有的素?cái)?shù)有 664579 個(gè) Numba裝飾器耗時(shí): 3.9410934448242188 秒 使用numba裝飾器,速度提升 22.0 倍
三、素?cái)?shù)算法
質(zhì)數(shù)也就是大于1的整數(shù)中,除了1和它本身以外不能被其他整數(shù)整除的數(shù),也叫素?cái)?shù)。
# 算法一:針對(duì)輸入的數(shù)字x,我們可以遍歷從2到x-1這個(gè)區(qū)間中的數(shù),如果x能被這個(gè)區(qū)間中任意一個(gè)數(shù)整除,那么它就不是質(zhì)數(shù)。 def is_prime1(x): for i in range(2, x): if x % i == 0: return False return True # 算法二:對(duì)算法一的優(yōu)化,事實(shí)上只需要遍歷從2到√x即可。 def is_prime2(x): for i in range(2, int(x ** 0.5) + 1): if x % i == 0: return False return True # 算法三:偶數(shù)中除了2都不是質(zhì)數(shù),且奇數(shù)的因數(shù)也沒(méi)有偶數(shù),因此可以進(jìn)一步優(yōu)化。 def is_prime3(x): if x == 2: return True elif x % 2 == 0: return False for i in range(3, int(x ** 0.5) + 1, 2): if x % i == 0: return False return True # 算法四:任何一個(gè)自然數(shù),總可以表示成以下六種形式之一:6n,6n+1,6n+2,6n+3,6n+4,6n+5(n=0,1,2...)我們可以發(fā)現(xiàn),除了2和3,只有形如6n+1和6n+5的數(shù)有可能是質(zhì)數(shù)。且形如6n+1和6n+5的數(shù)如果不是質(zhì)數(shù),它們的因數(shù)也會(huì)含有形如6n+1或者6n+5的數(shù),因此可以得到如下算法: def is_prime4(x): if (x == 2) or (x == 3): return True if (x % 6 != 1) and (x % 6 != 5): return False for i in range(5, int(x ** 0.5) + 1, 6): if (x % i == 0) or (x % (i + 2) == 0): return False return True
四、Numba
4.1 官方文檔
numba 是一款可以將 python 函數(shù)編譯為機(jī)器代碼的JIT編譯器,經(jīng)過(guò) numba 編譯的python 代碼(僅限數(shù)組運(yùn)算),其運(yùn)行速度可以接近 C 或 FORTRAN 語(yǔ)言。
官方文檔鏈接:http://numba.pydata.org/numba-doc/latest/index.html
到此這篇關(guān)于Python中Numba庫(kù)裝飾器的具體使用的文章就介紹到這了,更多相關(guān)Python Numba庫(kù)裝飾器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python3二分查找?guī)旌瘮?shù)bisect(),bisect_left()和bisect_right()的區(qū)別
這篇文章主要介紹了Python3二分查找?guī)旌瘮?shù)bisect(),bisect_left()和bisect_right()的區(qū)別,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03Python 多模式字符串搜索 Aho-Corasick詳解
Aho-Corasick 算法是一種用于精確或近似多模式字符串搜索的高效算法,本文給大家介紹Python 多模式字符串搜索 Aho-Corasick的相關(guān)知識(shí),感興趣的朋友跟隨小編一起看看吧2025-01-01關(guān)于python通過(guò)新建環(huán)境安裝tfx的問(wèn)題
這篇文章主要介紹了python安裝tfx/新建環(huán)境,新建一個(gè)環(huán)境tfx專門(mén)用來(lái)運(yùn)行流水線,這個(gè)環(huán)境安裝python3.8,對(duì)python安裝tfx相關(guān)知識(shí)感興趣的朋友一起看看吧2022-05-05