Python性能優(yōu)化之讓你的代碼運(yùn)行速度提升10倍的技巧分享
在日常開發(fā)中,我們常常會(huì)遇到Python代碼運(yùn)行緩慢的問題。雖然Python以其簡潔優(yōu)雅著稱,但性能往往不是它的強(qiáng)項(xiàng)。不過,通過一些巧妙的優(yōu)化技巧,我們完全可以讓代碼的運(yùn)行速度提升數(shù)倍甚至數(shù)十倍。今天,我將分享一些實(shí)戰(zhàn)中驗(yàn)證過的性能優(yōu)化方法。
1. 選擇正確的數(shù)據(jù)結(jié)構(gòu)
數(shù)據(jù)結(jié)構(gòu)的選擇對性能影響巨大。使用合適的數(shù)據(jù)結(jié)構(gòu),往往能帶來指數(shù)級(jí)的性能提升。
使用set進(jìn)行查找操作
當(dāng)需要頻繁判斷元素是否存在時(shí),set的查找時(shí)間復(fù)雜度是O(1),而list是O(n)。
# 慢速版本
def find_in_list(items, targets):
result = []
for target in targets:
if target in items: # O(n) 查找
result.append(target)
return result
# 快速版本
def find_in_set(items, targets):
items_set = set(items) # 一次性轉(zhuǎn)換
result = []
for target in targets:
if target in items_set: # O(1) 查找
result.append(target)
return result
使用dict代替多個(gè)if-elif
# 慢速版本
def get_discount(level):
if level == 'bronze':
return 0.05
elif level == 'silver':
return 0.10
elif level == 'gold':
return 0.15
elif level == 'platinum':
return 0.20
else:
return 0
# 快速版本
def get_discount(level):
discounts = {
'bronze': 0.05,
'silver': 0.10,
'gold': 0.15,
'platinum': 0.20
}
return discounts.get(level, 0)
2. 利用內(nèi)置函數(shù)和標(biāo)準(zhǔn)庫
Python的內(nèi)置函數(shù)用C語言實(shí)現(xiàn),速度遠(yuǎn)快于純Python代碼。
使用map和filter
# 慢速版本
numbers = range(1000000)
result = []
for num in numbers:
result.append(num * 2)
# 快速版本
numbers = range(1000000)
result = list(map(lambda x: x * 2, numbers))
# 更快:列表推導(dǎo)式
result = [num * 2 for num in numbers]
利用collections模塊
from collections import Counter, defaultdict, deque
# 統(tǒng)計(jì)元素出現(xiàn)次數(shù)
words = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']
# 快速統(tǒng)計(jì)
count = Counter(words)
# 使用defaultdict避免鍵檢查
word_positions = defaultdict(list)
for i, word in enumerate(words):
word_positions[word].append(i)
# 使用deque實(shí)現(xiàn)高效的隊(duì)列操作
queue = deque()
queue.append(1) # O(1)
queue.popleft() # O(1),list.pop(0)是O(n)
3. 避免不必要的計(jì)算
緩存重復(fù)計(jì)算結(jié)果
from functools import lru_cache
# 慢速版本:重復(fù)計(jì)算
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
# 快速版本:使用緩存
@lru_cache(maxsize=None)
def fibonacci_cached(n):
if n < 2:
return n
return fibonacci_cached(n-1) + fibonacci_cached(n-2)
# fibonacci(35) 可能需要幾秒
# fibonacci_cached(35) 幾乎瞬間完成
延遲計(jì)算和生成器
# 慢速版本:一次性創(chuàng)建所有數(shù)據(jù)
def process_large_file(filename):
with open(filename) as f:
lines = f.readlines() # 一次性讀入內(nèi)存
return [line.strip().upper() for line in lines]
# 快速版本:使用生成器
def process_large_file_lazy(filename):
with open(filename) as f:
for line in f: # 逐行處理
yield line.strip().upper()
# 使用
for processed_line in process_large_file_lazy('huge_file.txt'):
# 處理每一行,內(nèi)存占用小
pass
4. 字符串操作優(yōu)化
字符串拼接是常見的性能瓶頸。
# 慢速版本:使用+拼接
def join_strings_slow(strings):
result = ""
for s in strings:
result += s # 每次創(chuàng)建新字符串對象
return result
# 快速版本:使用join
def join_strings_fast(strings):
return "".join(strings)
# 性能對比:處理10000個(gè)字符串
# 慢速版本:約0.5秒
# 快速版本:約0.001秒(快500倍)
5. 循環(huán)優(yōu)化技巧
減少點(diǎn)號(hào)查找
import math
# 慢速版本
def calculate_slow(numbers):
result = []
for num in numbers:
result.append(math.sqrt(num)) # 每次都要查找math.sqrt
return result
# 快速版本
def calculate_fast(numbers):
sqrt = math.sqrt # 局部變量查找更快
result = []
for num in numbers:
result.append(sqrt(num))
return result
# 更快:列表推導(dǎo)式
def calculate_fastest(numbers):
sqrt = math.sqrt
return [sqrt(num) for num in numbers]
使用enumerate代替range(len())
items = ['a', 'b', 'c', 'd']
# 慢速版本
for i in range(len(items)):
print(i, items[i])
# 快速版本
for i, item in enumerate(items):
print(i, item)
6. 并行處理和多線程
對于CPU密集型任務(wù),使用多進(jìn)程;對于IO密集型任務(wù),使用多線程或異步IO。
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
import time
# CPU密集型任務(wù)示例
def cpu_bound_task(n):
return sum(i * i for i in range(n))
# 使用多進(jìn)程
def process_with_multiprocessing(numbers):
with ProcessPoolExecutor() as executor:
results = list(executor.map(cpu_bound_task, numbers))
return results
# IO密集型任務(wù)使用多線程
import requests
def download_url(url):
response = requests.get(url)
return len(response.content)
def download_parallel(urls):
with ThreadPoolExecutor(max_workers=10) as executor:
results = list(executor.map(download_url, urls))
return results
7. 使用NumPy進(jìn)行數(shù)值計(jì)算
對于數(shù)值計(jì)算,NumPy比純Python快幾十倍甚至上百倍。
import numpy as np
# 慢速版本:純Python
def sum_of_squares_python(n):
return sum(i**2 for i in range(n))
# 快速版本:NumPy
def sum_of_squares_numpy(n):
arr = np.arange(n)
return np.sum(arr**2)
# 性能對比(n=1000000)
# Python版本:約0.5秒
# NumPy版本:約0.01秒(快50倍)
8. 性能分析工具
找出性能瓶頸比盲目優(yōu)化更重要。
import cProfile
import pstats
# 使用cProfile分析
def my_function():
# 你的代碼
pass
profiler = cProfile.Profile()
profiler.enable()
my_function()
profiler.disable()
stats = pstats.Stats(profiler)
stats.sort_stats('cumulative')
stats.print_stats(10) # 顯示最慢的10個(gè)函數(shù)
# 使用line_profiler進(jìn)行行級(jí)分析
# pip install line_profiler
# 在函數(shù)前添加@profile裝飾器
# 運(yùn)行:kernprof -l -v script.py
9. 避免全局變量
局部變量的訪問速度比全局變量快。
GLOBAL_LIST = list(range(10000))
# 慢速版本
def process_global():
result = 0
for item in GLOBAL_LIST:
result += item
return result
# 快速版本
def process_local():
local_list = GLOBAL_LIST # 創(chuàng)建局部引用
result = 0
for item in local_list:
result += item
return result
10. 使用__slots__優(yōu)化類
對于需要?jiǎng)?chuàng)建大量實(shí)例的類,使用__slots__可以顯著減少內(nèi)存占用并提升速度。
# 普通類
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
# 優(yōu)化類
class PointOptimized:
__slots__ = ['x', 'y']
def __init__(self, x, y):
self.x = x
self.y = y
# 創(chuàng)建100萬個(gè)實(shí)例
# 普通類:約300MB內(nèi)存
# 優(yōu)化類:約150MB內(nèi)存(節(jié)省50%)
總結(jié)
Python性能優(yōu)化是一門藝術(shù),需要在代碼可讀性和執(zhí)行效率之間找到平衡。記住以下幾個(gè)原則:
- 先分析再優(yōu)化:使用性能分析工具找出真正的瓶頸
- 選擇正確的數(shù)據(jù)結(jié)構(gòu):這往往是最有效的優(yōu)化
- 利用標(biāo)準(zhǔn)庫:內(nèi)置函數(shù)和標(biāo)準(zhǔn)庫通常已經(jīng)優(yōu)化得很好
- 避免重復(fù)計(jì)算:使用緩存和生成器
- 考慮并行處理:充分利用多核CPU
- 必要時(shí)使用C擴(kuò)展:如NumPy、Pandas等
記住,過早優(yōu)化是萬惡之源。首先寫出清晰正確的代碼,然后用數(shù)據(jù)驅(qū)動(dòng)優(yōu)化決策。通過合理運(yùn)用這些技巧,你的Python代碼性能提升10倍完全不是夢想!
到此這篇關(guān)于Python性能優(yōu)化之讓你的代碼運(yùn)行速度提升10倍的技巧分享的文章就介紹到這了,更多相關(guān)Python性能優(yōu)化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python OpenCV實(shí)現(xiàn)視頻追蹤
這篇文章主要為大家詳細(xì)介紹了Python OpenCV實(shí)現(xiàn)視頻追蹤,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08
python和opencv構(gòu)建運(yùn)動(dòng)檢測器的實(shí)現(xiàn)
這篇文章主要介紹了python和opencv構(gòu)建運(yùn)動(dòng)檢測器的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
pytorch深度神經(jīng)網(wǎng)絡(luò)入門準(zhǔn)備自己的圖片數(shù)據(jù)
這篇文章主要為大家介紹了pytorch深度神經(jīng)網(wǎng)絡(luò)入門準(zhǔn)備自己的圖片數(shù)據(jù)示例過程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
python安裝cxOracle避坑總結(jié)不要直接pip install
這篇文章主要為大家介紹了python安裝cx_Oracle是遇到的一些問題的解決辦法的總結(jié),來幫大家避避坑有需要的朋友可以借鑒參考下,希望能夠有所幫助祝大家多多進(jìn)步2021-10-10
新手常犯的10個(gè)Python錯(cuò)誤及解決方法總結(jié)
在學(xué)習(xí) Python 的過程中,新手開發(fā)者經(jīng)常會(huì)遇到一些常見的錯(cuò)誤,今天,就讓我們一起看看這些常見錯(cuò)誤及其解決方法,幫助你更快地掌握 Python 編程2025-10-10
python執(zhí)行系統(tǒng)命令4種方法與比較
這篇文章主要介紹了python執(zhí)行系統(tǒng)命令4種方法與比較,需要的朋友可以參考下2021-04-04

