五個(gè)提升Python的執(zhí)行效率的技巧分享
python作為使用最廣泛的編程語(yǔ)言之一,有著無(wú)窮無(wú)盡的第三方非標(biāo)準(zhǔn)庫(kù)的支持。
簡(jiǎn)單的語(yǔ)法、優(yōu)雅的代碼塊使其在各個(gè)業(yè)務(wù)領(lǐng)域都混的風(fēng)生水起,除了這些優(yōu)點(diǎn),python有一個(gè)經(jīng)常被人詬病的缺點(diǎn)那就是運(yùn)行速度。
小伙伴通過(guò)下面的五個(gè)python開發(fā)技巧,來(lái)充分提高python代碼塊的運(yùn)行速度,并且提供了各個(gè)python技巧的使用后的運(yùn)行時(shí)間的統(tǒng)計(jì)來(lái)佐證。
開始之前小伙伴先可以開發(fā)一個(gè)統(tǒng)計(jì)函數(shù)運(yùn)行時(shí)間的python裝飾器用于后面我們對(duì)各個(gè)python技巧使用后的時(shí)間統(tǒng)計(jì)。
#?導(dǎo)入時(shí)間提取的time模塊 from?time?import?time import?dis def?compute_time(func_): ????''' ????計(jì)算函數(shù)的運(yùn)行時(shí)間 ????''' ????def?func_time(*arg,?**kw): ????????t1?=?time() ????????result?=?func_(*arg,?**kw) ????????t2?=?time() ????????print(f"{func_.__name__:?>10}?:?{t2?-?t1:.6f}?秒") ????????return?result ????return?func_time
上述的compute_time時(shí)間計(jì)算函數(shù)我們開發(fā)好了,可以開發(fā)一個(gè)hello_world函數(shù)測(cè)試一下使用是否正常。
@compute_time def?hello_world(): ????print("hello_world!") hello_world() #?hello_world! #?hello_world?:?0.000000?秒
通過(guò)hello_world函數(shù)的測(cè)試,證明我們的時(shí)間裝飾器compute_time能夠正常統(tǒng)計(jì)出函數(shù)所運(yùn)行的時(shí)間。
接下來(lái),我們開始正式的介紹下面的五種方式來(lái)提高python的運(yùn)行速度并提供時(shí)間運(yùn)行的結(jié)果。
1、合理使用標(biāo)準(zhǔn)或非標(biāo)準(zhǔn)庫(kù)
在開發(fā)過(guò)程中絕對(duì)不能小看python的標(biāo)準(zhǔn)或非標(biāo)準(zhǔn)庫(kù),說(shuō)實(shí)話我們自己有時(shí)候?qū)懙耐瑯拥臉I(yè)務(wù)代碼塊確實(shí)是沒(méi)有大佬們完美。
比如下面這個(gè)業(yè)務(wù)我們需要將一個(gè)python列表中的值轉(zhuǎn)換成字符串,首先看看下面的代碼塊的寫法。
#?初始化一個(gè)list列表 list_?=?['a',?'b',?'c']?*?10000 @compute_time def?func_1(list_=None): ????''' ????列表元素轉(zhuǎn)字符串函數(shù) ????''' ????str_?=?'' ????for?s?in?list_: ????????str_?=?str_?+?s ????return?str_ func_1(list_) #?func_1?:?0.001999?秒
通過(guò)上面的func_1函數(shù)的執(zhí)行情況使用自己寫的傳統(tǒng)的方式來(lái)轉(zhuǎn)換步驟比較繁雜,并且花費(fèi)了0.001999 秒的時(shí)間。
@compute_time def?func_2(list_=None): ????''' ????列表元素轉(zhuǎn)字符串 ????''' ????return?''.join(list_) func_2(list_) #?func_2?:?0.000000?秒
相比f(wàn)unc_1函數(shù)的運(yùn)行時(shí)間,func_2運(yùn)行的時(shí)間幾乎可以忽略不計(jì),六位數(shù)的小數(shù)根本看不出來(lái)變化。
2、減少循環(huán)的使用
從平常開發(fā)的過(guò)程中其實(shí)已經(jīng)發(fā)現(xiàn),使用列表推導(dǎo)式、迭代式等的可序列化數(shù)據(jù)處理方式要比f(wàn)or循環(huán)更加的便捷、高效。
下面我們同樣可以通過(guò)一個(gè)例子來(lái)說(shuō)明問(wèn)題,比如我們需要挑選出一個(gè)list列表中可以被2整除的數(shù)。
#?初始化循環(huán)次數(shù)n n?=?100000 @compute_time def?func_3(n=None): ????list_?=?[] ????for?m?in?range(n): ????????if?m?%?2?==?0: ????????????list_.append(m) ????return?list_ @compute_time def?func_4(n=None): ????return?[m?for?m?in?range(n)?if?m?%?2?==?0] func_3(n) func_4(n) #?func_3?:?0.004986?秒 #?func_4?:?0.003014?秒
通過(guò)func_3函數(shù)、func_4函數(shù)的比較,首先f(wàn)unc_4的方式比f(wàn)unc_3精簡(jiǎn)了許多。
并且時(shí)間上func_4使用列表推導(dǎo)式的方式比普通的for循環(huán)運(yùn)行速度上快了1/4的時(shí)間。
3、注意重復(fù)代碼運(yùn)行
關(guān)于代碼的重復(fù)運(yùn)行這個(gè)在我們通常的開發(fā)方式中都能體會(huì)到,也就是本可以作為公共代碼塊運(yùn)行一次就可以。
可以卻將能夠公共使用的代碼塊加入到了循環(huán)當(dāng)中,這樣只會(huì)影響代碼塊的執(zhí)行效率。
比如我們需要使用python的re模塊去搜索字符串中的某一些元素,下面通過(guò)兩種方式來(lái)比較時(shí)間結(jié)果。
#?導(dǎo)入正則表達(dá)式匹配模塊 import?re @compute_time def?func_5(str_=None): ????for?s?in?str_: ????????result?=?re.search(r'a*[a-z]?c',?s) @compute_time def?func_6(str_=None): ????repx?=?re.compile(r'a*[a-z]?c') ????for?s?in?str_: ????????result?=?repx.search(s) func_5('abcdefg1234oks'?*?1000) func_6('abcdefg1234oks'?*?1000) #?func_5?:?0.006999?秒 #?func_6?:?0.002000?秒
對(duì)比f(wàn)unc_5和func_6的業(yè)務(wù)實(shí)現(xiàn)方式,我們將re模塊的compile正則匹配對(duì)象直接放到for循環(huán)的外層,運(yùn)行時(shí)間直接就減少了3倍不止。
是因?yàn)樵谘h(huán)中直接使用search匹配正則對(duì)象,會(huì)在循環(huán)中不斷地創(chuàng)建正則匹配對(duì)象,這樣就
增加了for循環(huán)的處理負(fù)擔(dān),導(dǎo)致速度變慢。
4、減少全局變量使用
在說(shuō)明這一點(diǎn)的時(shí)候,我們要明白全局變量在程序運(yùn)行的過(guò)程中是一直存在的不會(huì)消失。
全局變量太多就會(huì)導(dǎo)致運(yùn)行期間占用的內(nèi)存太大,相比全局變量使用局部變量就會(huì)變得更加的高效。
下面我們通過(guò)兩種方式的使用實(shí)例,來(lái)對(duì)比全局變量和局部變量的運(yùn)行時(shí)間。
mes_1?=?'ss1' mes_2?=?'ss2' mes_3?=?'ss3' @compute_time def?func_7(): ????result?=?mes_1?+?mes_2?+?mes_3 ????return?result @compute_time def?func_8(): ????me_1?=?'ss1' ????me_2?=?'ss2' ????me_3?=?'ss3' ????result?=?me_1?+?me_2?+?me_3 ????return?result func_7() func_8() #?func_7?:?0.000997?秒 #?func_8?:?0.000000?秒
上面我們做了一個(gè)普通的加法計(jì)算已經(jīng)說(shuō)明了問(wèn)題,func_8函數(shù)使用局部變量的方式確實(shí)速度更快。
5、使用合理的數(shù)據(jù)結(jié)構(gòu)
在大多數(shù)的python開發(fā)過(guò)程中,想必很多人都是為了方便更多的時(shí)候使用的是list列表的方式來(lái)處理數(shù)據(jù)。
Python 有四種內(nèi)置的數(shù)據(jù)結(jié)構(gòu):列表、元組、集合、字典,在合適的業(yè)務(wù)場(chǎng)景中使用合適的數(shù)據(jù)結(jié)構(gòu)來(lái)處理數(shù)據(jù)同樣能提高計(jì)算的執(zhí)行效率。
比如:下面我們將從一個(gè)list列表和tuple元組來(lái)提取對(duì)應(yīng)索引位置上面的值。
@compute_time def?func_9(): ????data?=?['a',?'b',?'c',?'d',?'e',?'f',?'g',?'h'] ????print(data[3]) @compute_time def?func_10(): ????data?=?('a',?'b',?'c',?'d',?'e',?'f',?'g',?'h') ????print(data[3]) func_9() func_10() #?func_9?:?0.000000?秒 #?func_10?:?0.000000?秒
通過(guò)執(zhí)行func_9和func_10函數(shù),我們發(fā)現(xiàn)時(shí)間上兩者的差距不大,起碼在六位小數(shù)之內(nèi)是分辨不出結(jié)果的。
print('func_9匯編產(chǎn)生的機(jī)器碼:') dis.dis(func_9) print('func_10匯編產(chǎn)生的機(jī)器碼:') dis.dis(func_10)
最后,我們分別查看了func_9和func_10的匯編機(jī)器碼,發(fā)現(xiàn)明顯list列表處理產(chǎn)生的機(jī)器碼更多。
# func_9匯編產(chǎn)生的機(jī)器碼: #??30???????????0?LOAD_GLOBAL??????????????0?(time) #???????????????2?CALL_FUNCTION????????????0 #???????????????4?STORE_FAST???????????????2?(t1) # #??31???????????6?LOAD_DEREF???????????????0?(func_) #???????????????8?LOAD_FAST????????????????0?(arg) #??????????????10?LOAD_FAST????????????????1?(kw) #??????????????12?CALL_FUNCTION_EX?????????1 #??????????????14?STORE_FAST???????????????3?(result) # #??32??????????16?LOAD_GLOBAL??????????????0?(time) #??????????????18?CALL_FUNCTION????????????0 #??????????????20?STORE_FAST???????????????4?(t2) # #??33??????????22?LOAD_GLOBAL??????????????1?(print) #??????????????24?LOAD_DEREF???????????????0?(func_) #??????????????26?LOAD_ATTR????????????????2?(__name__) #??????????????28?LOAD_CONST???????????????1?('?>10') #??????????????30?FORMAT_VALUE?????????????4?(with?format) #??????????????32?LOAD_CONST???????????????2?('?:?') #??????????????34?LOAD_FAST????????????????4?(t2) #??????????????36?LOAD_FAST????????????????2?(t1) #??????????????38?BINARY_SUBTRACT #??????????????40?LOAD_CONST???????????????3?('.6f') #??????????????42?FORMAT_VALUE?????????????4?(with?format) #??????????????44?LOAD_CONST???????????????4?('?秒') #??????????????46?BUILD_STRING?????????????4 #??????????????48?CALL_FUNCTION????????????1 #??????????????50?POP_TOP # #??34??????????52?LOAD_FAST????????????????3?(result) #??????????????54?RETURN_VALUE # func_10匯編產(chǎn)生的機(jī)器碼: #??30???????????0?LOAD_GLOBAL??????????????0?(time) #???????????????2?CALL_FUNCTION????????????0 #???????????????4?STORE_FAST???????????????2?(t1) # #??31???????????6?LOAD_DEREF???????????????0?(func_) #???????????????8?LOAD_FAST????????????????0?(arg) #??????????????10?LOAD_FAST????????????????1?(kw) #??????????????12?CALL_FUNCTION_EX?????????1 #??????????????14?STORE_FAST???????????????3?(result)
到此這篇關(guān)于五個(gè)提升Python的執(zhí)行效率的技巧分享的文章就介紹到這了,更多相關(guān)Python提升執(zhí)行效率技巧內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python apscheduler實(shí)現(xiàn)定時(shí)任務(wù)的方法詳解
apscheduler(Advanced Python Scheduler)是一個(gè)用于Python的靈活、強(qiáng)大的定時(shí)任務(wù)調(diào)度庫(kù),它允許您以各種方式安排函數(shù)或方法的執(zhí)行,下面就跟隨小編一起學(xué)習(xí)一下它的具體使用吧2023-10-10python編寫簡(jiǎn)易聊天室實(shí)現(xiàn)局域網(wǎng)內(nèi)聊天功能
這篇文章主要為大家詳細(xì)介紹了python編寫簡(jiǎn)易聊天室實(shí)現(xiàn)局域網(wǎng)內(nèi)聊天功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07Python將8位的圖片轉(zhuǎn)為24位的圖片實(shí)現(xiàn)方法
這篇文章主要介紹了Python將8位的圖片轉(zhuǎn)為24位的圖片的實(shí)現(xiàn)代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-10-10利用Python+PyQt5實(shí)現(xiàn)簡(jiǎn)易瀏覽器的實(shí)戰(zhàn)記錄
這篇文章主要給大家介紹了關(guān)于如何利用Python+PyQt5實(shí)現(xiàn)簡(jiǎn)易瀏覽器的相關(guān)資料,Qt 的主要優(yōu)勢(shì)是可以開發(fā)跨平臺(tái)的圖形界面程序,基于 Qt 的應(yīng)用能夠借助于各平臺(tái)的原生性在不同類的設(shè)備上運(yùn)行,而無(wú)須修改任何代碼庫(kù),需要的朋友可以參考下2021-07-07Python將運(yùn)行結(jié)果導(dǎo)出為CSV格式的兩種常用方法
這篇文章主要給大家介紹了關(guān)于Python將運(yùn)行結(jié)果導(dǎo)出為CSV格式的兩種常用方法,Python生成(導(dǎo)出)csv文件其實(shí)很簡(jiǎn)單,我們一般可以用csv模塊或者pandas庫(kù)來(lái)實(shí)現(xiàn),需要的朋友可以參考下2023-07-07Python中如何優(yōu)雅的合并兩個(gè)字典(dict)方法示例
字典是Python語(yǔ)言中唯一的映射類型,在我們?nèi)粘9ぷ髦薪?jīng)常會(huì)遇到,下面這篇文章主要給大家介紹了關(guān)于Python中如何優(yōu)雅的合并兩個(gè)字典(dict)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-08-08Python調(diào)用微信公眾平臺(tái)接口操作示例
這篇文章主要介紹了Python調(diào)用微信公眾平臺(tái)接口操作,結(jié)合具體實(shí)例形式分析了Python針對(duì)微信接口數(shù)據(jù)傳輸?shù)南嚓P(guān)操作技巧,需要的朋友可以參考下2017-07-07