5個(gè)Python性能優(yōu)化技巧分享(代碼提速300%)
今天咱們來(lái)聊聊一個(gè)每個(gè)開(kāi)發(fā)者都關(guān)心的話題——如何讓Python代碼跑得更快!對(duì)于很多Python初學(xué)者來(lái)說(shuō),可能沒(méi)太多接觸過(guò)性能優(yōu)化的技巧,只知道“Python慢”,但其實(shí),你完全可以通過(guò)一些簡(jiǎn)單的優(yōu)化技巧,讓你的代碼飛起來(lái),給自己和團(tuán)隊(duì)帶來(lái)巨大的提升。
接下來(lái)我們看看怎么提升Python代碼的速度吧!
1. 避免不必要的循環(huán)和冗余計(jì)算
首先,我們從最基礎(chǔ)的開(kāi)始。你有沒(méi)有發(fā)現(xiàn),有些代碼在執(zhí)行時(shí)似乎做了很多重復(fù)的計(jì)算,而這些計(jì)算是完全不必要的?
例子:
假設(shè)我們有個(gè)程序要對(duì)一組數(shù)據(jù)做求和計(jì)算,代碼是這樣寫(xiě)的:
def calculate_sum(data): total = 0 for i in range(len(data)): total += data[i] return total
看起來(lái)沒(méi)什么問(wèn)題吧?但是,我們每次都通過(guò) data[i]
來(lái)訪問(wèn)元素,這其實(shí)很慢。你能猜到怎么優(yōu)化嗎?
優(yōu)化:
我們可以使用 sum()
函數(shù),它是Python內(nèi)置的,速度比手動(dòng)計(jì)算要快得多:
def calculate_sum(data): return sum(data)
簡(jiǎn)單吧?看起來(lái)沒(méi)什么特別,但你會(huì)發(fā)現(xiàn),運(yùn)行這種代碼的速度會(huì)提高幾個(gè)數(shù)量級(jí)!
原理:
sum()
是Python的內(nèi)建函數(shù),它內(nèi)部做了很多優(yōu)化,比如使用C語(yǔ)言實(shí)現(xiàn),這就是為什么它比我們手寫(xiě)的循環(huán)要快得多。所以,對(duì)于大部分簡(jiǎn)單的數(shù)學(xué)運(yùn)算,Python內(nèi)置的函數(shù)通常是最優(yōu)解。
2. 使用列表生成式(List Comprehensions)代替普通循環(huán)
讓我們?cè)賮?lái)看看一個(gè)常見(jiàn)的優(yōu)化場(chǎng)景:如果你用普通的for循環(huán)來(lái)創(chuàng)建一個(gè)列表,實(shí)際上這會(huì)比列表生成式(list comprehension)要慢。
例子:
假如我們需要生成一個(gè)包含100萬(wàn)個(gè)平方數(shù)的列表:
def generate_squares(n): squares = [] for i in range(n): squares.append(i**2) return squares
這個(gè)方法沒(méi)錯(cuò),但它有點(diǎn)“笨重”。你能想到更簡(jiǎn)潔、更高效的方式嗎?
優(yōu)化:
我們可以用列表生成式來(lái)替代普通的循環(huán):
def generate_squares(n): return [i**2 for i in range(n)]
原理:
列表生成式的背后,其實(shí)是通過(guò)高效的內(nèi)存管理來(lái)加速處理的,它比傳統(tǒng)的循環(huán)操作要少很多不必要的內(nèi)存分配,所以速度更快。
3. 避免頻繁的內(nèi)存分配
內(nèi)存分配的開(kāi)銷(xiāo)對(duì)于程序來(lái)說(shuō)是非常大的,頻繁的分配和回收內(nèi)存就像你家搬家一樣,麻煩又浪費(fèi)時(shí)間。如果你的代碼在某些地方頻繁創(chuàng)建臨時(shí)對(duì)象或者數(shù)據(jù)結(jié)構(gòu),這樣做會(huì)降低性能。
例子:
假設(shè)我們需要?jiǎng)?chuàng)建一個(gè)列表,長(zhǎng)度為100萬(wàn),我們用 for
循環(huán)不斷地向列表添加元素:
def create_list(n): result = [] for i in range(n): result.append(i) return result
這個(gè)方法有點(diǎn)小問(wèn)題,因?yàn)槊看握{(diào)用 append()
時(shí),Python都要在內(nèi)存中動(dòng)態(tài)調(diào)整列表的大小。
優(yōu)化:
我們可以一次性預(yù)先分配好列表的大小,這樣就避免了多次內(nèi)存分配的開(kāi)銷(xiāo):
def create_list(n): result = [None] * n # 預(yù)先分配內(nèi)存 for i in range(n): result[i] = i return result
原理:
通過(guò)提前分配內(nèi)存,你就減少了頻繁進(jìn)行內(nèi)存重新分配的需要,能顯著提高性能。
4. 使用生成器代替列表
說(shuō)到內(nèi)存開(kāi)銷(xiāo),另一個(gè)值得注意的地方就是:如果你處理的數(shù)據(jù)集非常大,完全不需要把所有數(shù)據(jù)都一次性加載到內(nèi)存中。在這種情況下,生成器(generator)是一個(gè)非常好的選擇。
例子:
假設(shè)你要讀取一個(gè)大文件并逐行處理數(shù)據(jù):
def read_file(filename): with open(filename, 'r') as f: data = f.readlines() # 一次性把所有行讀進(jìn)內(nèi)存 return data
如果文件特別大,像這種一次性把數(shù)據(jù)全部加載到內(nèi)存的做法就不太理想了。
優(yōu)化:
可以改成生成器,按需加載數(shù)據(jù),這樣每次只加載一行,節(jié)省內(nèi)存:
def read_file(filename): with open(filename, 'r') as f: for line in f: yield line # 每次返回一行數(shù)據(jù)
原理:
生成器的好處在于它是懶加載的,只有在你需要數(shù)據(jù)時(shí),才會(huì)從文件中讀取一行。這就避免了將所有數(shù)據(jù)一次性加載到內(nèi)存中,節(jié)省了大量?jī)?nèi)存。
5. 利用多線程或多進(jìn)程來(lái)并行處理任務(wù)
最后,我們來(lái)聊聊如何讓Python更“能干”地同時(shí)做多個(gè)事情。你可能知道,Python的GIL(全局解釋器鎖)會(huì)限制多線程的并發(fā)執(zhí)行,但這并不代表你不能利用多線程或者多進(jìn)程來(lái)提高性能!
例子:
假設(shè)我們需要下載多個(gè)文件,如果一個(gè)個(gè)按順序下載,速度就會(huì)很慢:
import time def download_file(url): time.sleep(1) # 模擬下載 print(f"下載完成: {url}") urls = ["url1", "url2", "url3", "url4"] for url in urls: download_file(url)
這個(gè)方法很直觀,但是需要1秒鐘下載一個(gè)文件。如果有上百個(gè)文件,豈不是要等很久?
優(yōu)化:
我們可以使用多線程或者多進(jìn)程同時(shí)下載多個(gè)文件,快速完成任務(wù):
import threading def download_file(url): time.sleep(1) print(f"下載完成: {url}") urls = ["url1", "url2", "url3", "url4"] threads = [] for url in urls: thread = threading.Thread(target=download_file, args=(url,)) thread.start() threads.append(thread) for thread in threads: thread.join()
原理:
通過(guò)多線程,程序能夠同時(shí)執(zhí)行多個(gè)任務(wù),減少了等待的時(shí)間。如果你想進(jìn)一步提速,考慮使用多進(jìn)程,尤其在計(jì)算密集型任務(wù)中。
總結(jié)
優(yōu)化Python代碼并不是一件高深的事。通過(guò)減少不必要的計(jì)算、使用Python的內(nèi)置工具、合理利用內(nèi)存和線程等,你就能讓代碼大幅提速。今天我們討論的5個(gè)技巧,看似簡(jiǎn)單,但每個(gè)都能帶來(lái)顯著的提升。
如果你現(xiàn)在還覺(jué)得這些技巧好像沒(méi)什么用,那試試用它們來(lái)優(yōu)化你手頭的代碼,絕對(duì)能看到效果。
到此這篇關(guān)于5個(gè)Python性能優(yōu)化技巧分享(代碼提速300%)的文章就介紹到這了,更多相關(guān)Python性能優(yōu)化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python 實(shí)現(xiàn)Harris角點(diǎn)檢測(cè)算法
這篇文章主要介紹了python 實(shí)現(xiàn)Harris角點(diǎn)檢測(cè)算法,幫助大家更好的利用python處理圖像,感興趣的朋友可以了解下2020-12-12Python Opencv任意形狀目標(biāo)檢測(cè)并繪制框圖
這篇文章主要為大家詳細(xì)介紹了Python Opencv任意形狀目標(biāo)檢測(cè),并繪制框圖,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07PyTorch上實(shí)現(xiàn)卷積神經(jīng)網(wǎng)絡(luò)CNN的方法
本篇文章主要介紹了PyTorch上實(shí)現(xiàn)卷積神經(jīng)網(wǎng)絡(luò)CNN的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-04-04pytorch中的nn.Unfold()函數(shù)和fold()函數(shù)解讀
這篇文章主要介紹了pytorch中的nn.Unfold()函數(shù)和fold()函數(shù)用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08