一文分析提升Python性能的10個智能技巧
Python 作為一門高效、簡潔且功能強(qiáng)大的編程語言,已經(jīng)廣泛應(yīng)用于從 Web 開發(fā)到人工智能等多個領(lǐng)域。然而,隨著項目的復(fù)雜性增加,性能瓶頸不可避免地浮現(xiàn)。尤其是在數(shù)據(jù)處理、實時系統(tǒng)和高性能計算方面,優(yōu)化 Python 代碼的執(zhí)行效率變得至關(guān)重要。幸運的是,Python 提供了很多內(nèi)置功能和優(yōu)化技巧,可以顯著提高代碼的運行速度。

以下是 10 個經(jīng)過實踐驗證的性能優(yōu)化策略,這些方法不依賴于外部庫,而是通過高效的數(shù)據(jù)結(jié)構(gòu)、低級優(yōu)化和 Python 本身的內(nèi)建功能來加速代碼執(zhí)行。通過這些技巧,你不僅可以在大數(shù)據(jù)集和計算密集型任務(wù)中獲得性能提升,還能在保持代碼簡潔和可讀性的同時,解決性能瓶頸。
技巧 1:使用集合進(jìn)行成員測試
在處理大規(guī)模數(shù)據(jù)集時,檢查某個元素是否在集合中,使用列表通常效率較低。列表的成員測試(x in some_list)是線性時間復(fù)雜度(O(n)),意味著它需要逐個掃描元素。而集合(set)則通過哈希表實現(xiàn),允許常數(shù)時間復(fù)雜度(O(1))的查找,效率大幅提升。
big_list = list(range(1000000))
big_set = set(big_list)
start = time.time()
print(999999 in big_list)
print(f"List lookup: {time.time() - start:.6f}s")
start = time.time()
print(999999 in big_set)
print(f"Set lookup: {time.time() - start:.6f}s")
時間測試結(jié)果:
- 列表查找:約 0.015 秒
- 集合查找:約 0.00002 秒
如果你的任務(wù)涉及到去重、輸入驗證或交叉引用等操作,集合會比列表更高效。
技巧 2:避免不必要的復(fù)制
復(fù)制大型對象(如列表、字典或數(shù)組)在時間和內(nèi)存上都是開銷巨大的。每次復(fù)制都會創(chuàng)建新的對象,這可能導(dǎo)致內(nèi)存浪費和性能下降,尤其在處理大數(shù)據(jù)集時。盡量使用原地操作而不是復(fù)制對象,Python 的許多內(nèi)置數(shù)據(jù)結(jié)構(gòu)都提供了原地操作的方法(如 sort、append、update 等)。
numbers = list(range(1000000))
def modify_list(lst):
lst[0] = 999
return lst
start = time.time()
result = modify_list(numbers)
print(f"In-place: {time.time() - start:.4f}s")
def copy_list(lst):
new_lst = lst.copy()
new_lst[0] = 999
return new_lst
start = time.time()
result = copy_list(numbers)
print(f"Copy: {time.time() - start:.4f}s")
時間測試結(jié)果:
- 原地修改:約 0.0001 秒
- 復(fù)制修改:約 0.0100 秒
技巧 3:使用__slots__來提高內(nèi)存效率
Python 類的實例屬性通常存儲在動態(tài)字典(__dict__)中,這為靈活性提供了便利,但也帶來了內(nèi)存開銷。通過使用 __slots__,可以顯式聲明固定的屬性集合,避免創(chuàng)建 __dict__,從而節(jié)省內(nèi)存。
class Point:
__slots__ = ('x', 'y')
def __init__(self, x, y):
self.x = x
self.y = y
start = time.time()
points = [Point(i, i+1) for i in range(1000000)]
print(f"With slots: {time.time() - start:.4f}s")
時間測試結(jié)果:
- 使用
__slots__:約 0.1200 秒 - 不使用
__slots__:約 0.1500 秒
技巧 4:使用math模塊代替操作符
Python 的 math 模塊提供了一些內(nèi)建的函數(shù),這些函數(shù)是用 C 實現(xiàn)的,比直接在 Python 中實現(xiàn)的運算符更加高效。例如,使用 math.sqrt() 通常比使用 ** 0.5 運算符來計算平方根要更快。
import math
numbers = list(range(10000000))
start = time.time()
roots = [math.sqrt(n) for n in numbers]
print(f"Math sqrt: {time.time() - start:.4f}s")
start = time.time()
roots = [n ** 0.5 for n in numbers]
print(f"Operator: {time.time() - start:.4f}s")
時間測試結(jié)果:
math.sqrt():約 0.2000 秒** 0.5:約 0.2500 秒
技巧 5:預(yù)分配已知大小的內(nèi)存
Python 在動態(tài)構(gòu)建列表或數(shù)組時,會在后臺進(jìn)行擴(kuò)容,每次擴(kuò)容都會涉及到內(nèi)存分配和數(shù)據(jù)復(fù)制。如果你知道數(shù)據(jù)結(jié)構(gòu)的最終大小,預(yù)先分配內(nèi)存能顯著提高性能,避免反復(fù)擴(kuò)容。
start = time.time()
result = [0] * 1000000
for i in range(1000000):
result[i] = i
print(f"Pre-allocated: {time.time() - start:.4f}s")
start = time.time()
result = []
for i in range(1000000):
result.append(i)
print(f"Dynamic: {time.time() - start:.4f}s")
時間測試結(jié)果:
- 預(yù)分配:約 0.0300 秒
- 動態(tài)分配:約 0.0400 秒
技巧 6:避免在熱循環(huán)中使用異常處理
異常處理非常強(qiáng)大,但它的開銷也不容小覷。尤其在性能關(guān)鍵的循環(huán)中,頻繁的拋出和捕獲異常會導(dǎo)致堆棧展開和上下文切換,這對性能有很大影響。在這些循環(huán)中,最好通過條件檢查來避免預(yù)期之外的錯誤發(fā)生,而不是依賴異常處理。
numbers = list(range(10000000))
start = time.time()
total = 0
for i in numbers:
if i % 2 != 0:
total += i // 2
else:
total += i
print(f"Conditional: {time.time() - start:.4f}s")
start = time.time()
total = 0
for i in numbers:
try:
total += i / (i % 2)
except ZeroDivisionError:
total += i
print(f"Exception: {time.time() - start:.4f}s")
時間測試結(jié)果:
- 條件檢查:約 0.3000 秒
- 異常處理:約 0.6000 秒
技巧 7:使用局部函數(shù)提高重復(fù)邏輯的效率
在函數(shù)中反復(fù)使用同一段邏輯時,定義一個局部(嵌套)函數(shù)可以提高性能,因為 Python 會在局部作用域內(nèi)更快地查找變量。
def outer():
def add_pair(a, b):
return a + b
result = 0
for i in range(10000000):
result = add_pair(result, i)
return result
start = time.time()
result = outer()
print(f"Local function: {time.time() - start:.4f}s")
def add_pair(a, b):
return a + b
start = time.time()
result = 0
for i in range(10000000):
result = add_pair(result, i)
print(f"Global function: {time.time() - start:.4f}s")
時間測試結(jié)果:
- 局部函數(shù):約 0.4000 秒
- 全局函數(shù):約 0.4500 秒
技巧 8:使用itertools進(jìn)行組合操作
Python 的 itertools 模塊提供了一些高效的函數(shù),適用于排列、組合、笛卡爾積等任務(wù)。這些函數(shù)采用惰性生成方式,能夠在不占用大量內(nèi)存的情況下處理大規(guī)模數(shù)據(jù)。
from itertools import product
items = [1, 2, 3] * 10
start = time.time()
result = list(product(items, repeat=2))
print(f"Itertools: {time.time() - start:.4f}s")
start = time.time()
result = []
for x in items:
for y in items:
result.append((x, y))
print(f"Loops: {time.time() - start:.4f}s")
時間測試結(jié)果:
itertools.product():約 0.0005 秒- 嵌套循環(huán):約 0.0020 秒
技巧 9:使用bisect進(jìn)行有序列表操作
如果你需要在一個有序列表中進(jìn)行查找或插入操作,使用 bisect 模塊提供的二分查找方法會比手動實現(xiàn)的
線性查找更加高效。
import bisect
sorted_list = list(range(1000000))
start = time.time()
bisect.insort(sorted_list, 500000)
print(f"Bisect insert: {time.time() - start:.4f}s")
start = time.time()
sorted_list.append(500000)
sorted_list.sort()
print(f"Manual insert: {time.time() - start:.4f}s")
時間測試結(jié)果:
bisect.insort():約 0.1000 秒- 手動插入:約 0.1500 秒
技巧 10:使用numpy進(jìn)行數(shù)值計算
對于數(shù)值計算密集型任務(wù),numpy 是一種非常高效的解決方案。相比純 Python 實現(xiàn),numpy 通過優(yōu)化的 C 代碼和向量化操作,能大幅提升計算效率。
import numpy as np
arr = np.arange(1000000)
start = time.time()
result = np.sqrt(arr)
print(f"NumPy: {time.time() - start:.4f}s")
start = time.time()
result = [x ** 0.5 for x in arr]
print(f"List comprehension: {time.time() - start:.4f}s")
時間測試結(jié)果:
numpy.sqrt():約 0.2000 秒- 列表推導(dǎo):約 0.4500 秒
結(jié)語
掌握這些 Python 性能優(yōu)化技巧,可以顯著提升你的代碼執(zhí)行效率,特別是在處理大量數(shù)據(jù)或需要高性能計算時。通過了解和運用 Python 內(nèi)置功能和高效的數(shù)據(jù)結(jié)構(gòu),不僅能提升運行速度,還能優(yōu)化代碼的可讀性和可維護(hù)性。
到此這篇關(guān)于一文分析提升Python性能的10個智能技巧的文章就介紹到這了,更多相關(guān)Python性能提升技巧內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
pyTorch深度學(xué)習(xí)多層感知機(jī)的實現(xiàn)
這篇文章主要為大家介紹了pyTorch深度學(xué)習(xí)多層感知機(jī)的實現(xiàn),文中附含詳細(xì)示例代碼,有需要的朋友可以借鑒參考下,希望能夠有所幫2021-09-09
DRF?QuerySet?Instance數(shù)據(jù)庫操作功能概述
這篇文章主要為大家介紹了DRF?QuerySet?Instance數(shù)據(jù)庫處理的功能概述,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10
Python sklearn中的.fit與.predict的用法說明
這篇文章主要介紹了Python sklearn中的.fit與.predict的用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06
詳解python的webrtc庫實現(xiàn)語音端點檢測
這篇文章主要介紹了詳解python的webrtc庫實現(xiàn)語音端點檢測,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-05-05
python+mysql實現(xiàn)教務(wù)管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了python+mysql實現(xiàn)教務(wù)管理系統(tǒng),具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-02-02

