15個(gè)Python運(yùn)行速度優(yōu)化技巧分享
1. 使用內(nèi)置函數(shù)和庫
Python自帶了很多高效的內(nèi)置函數(shù)和庫,它們通常比你自己寫的代碼要快得多。盡量使用這些現(xiàn)成的工具,而不是自己重新發(fā)明輪子。
示例:
# 不推薦:手動(dòng)計(jì)算列表元素之和 def sum_list_manual(lst): total = 0 for num in lst: total += num return total # 推薦:使用內(nèi)置sum函數(shù) def sum_list_builtin(lst): return sum(lst) # 測試 numbers = [1, 2, 3, 4, 5] print(sum_list_manual(numbers)) # 輸出: 15 print(sum_list_builtin(numbers)) # 輸出: 15
2. 使用列表推導(dǎo)式代替循環(huán)
列表推導(dǎo)式不僅更簡潔,而且執(zhí)行速度也更快。
示例:
# 不推薦:使用for循環(huán)創(chuàng)建平方數(shù)列表 squares_loop = [] for i in range(10): squares_loop.append(i ** 2) # 推薦:使用列表推導(dǎo)式 squares_comprehension = [i ** 2 for i in range(10)] print(squares_loop) # 輸出: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] print(squares_comprehension) # 輸出: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
3. 使用生成器表達(dá)式節(jié)省內(nèi)存
當(dāng)你處理大數(shù)據(jù)集時(shí),生成器表達(dá)式可以節(jié)省大量內(nèi)存,因?yàn)樗辉谛枰獣r(shí)生成數(shù)據(jù)。
示例:
# 不推薦:使用列表存儲(chǔ)所有平方數(shù) squares_list = [i ** 2 for i in range(1000000)] # 推薦:使用生成器表達(dá)式 squares_generator = (i ** 2 for i in range(1000000)) # 計(jì)算總和 print(sum(squares_list)) # 需要大量內(nèi)存 print(sum(squares_generator)) # 內(nèi)存使用較少
4. 使用set進(jìn)行成員檢查
集合(set
)的數(shù)據(jù)結(jié)構(gòu)查找元素的時(shí)間復(fù)雜度是O(1),而列表(list
)是O(n)。因此,如果需要頻繁進(jìn)行成員檢查,使用set
會(huì)更快。
示例:
# 不推薦:使用列表進(jìn)行成員檢查 my_list = list(range(1000000)) if 999999 in my_list: print("Found!") # 推薦:使用集合進(jìn)行成員檢查 my_set = set(range(1000000)) if 999999 in my_set: print("Found!")
5. 使用字典代替多重條件判斷
當(dāng)有多個(gè)條件判斷時(shí),可以考慮使用字典來簡化代碼,并提高效率。
示例:
# 不推薦:使用多重if-else def get_grade(score): if score >= 90: return 'A' elif score >= 80: return 'B' elif score >= 70: return 'C' else: return 'D' # 推薦:使用字典映射 grade_mapping = { (90, 100): 'A', (80, 89): 'B', (70, 79): 'C', (0, 69): 'D' } def get_grade_dict(score): for key, value in grade_mapping.items(): if key[0] <= score <= key[1]: return value print(get_grade(85)) # 輸出: B print(get_grade_dict(85)) # 輸出: B
6. 使用局部變量提高性能
局部變量的訪問速度比全局變量快。因此,在循環(huán)中盡量使用局部變量。
示例:
# 不推薦:使用全局變量 global_var = 10 def increment_global(): global global_var for _ in range(1000000): global_var += 1 # 推薦:使用局部變量 def increment_local(): local_var = 10 for _ in range(1000000): local_var += 1 increment_global() # 較慢 increment_local() # 較快
7. 使用functools.lru_cache緩存結(jié)果
對于耗時(shí)的函數(shù)調(diào)用,可以使用functools.lru_cache
來緩存結(jié)果,避免重復(fù)計(jì)算。
示例:
import functools # 不推薦:每次調(diào)用都重新計(jì)算 def fibonacci(n): if n <= 1: return n return fibonacci(n-1) + fibonacci(n-2) # 推薦:使用緩存 @functools.lru_cache(maxsize=None) def fibonacci_cached(n): if n <= 1: return n return fibonacci_cached(n-1) + fibonacci_cached(n-2) print(fibonacci(30)) # 較慢 print(fibonacci_cached(30)) # 較快
8. 使用numpy處理數(shù)值計(jì)算
numpy
是一個(gè)專門用于科學(xué)計(jì)算的庫,它提供了高效的數(shù)組操作功能。
示例:
import numpy as np # 不推薦:使用純Python列表進(jìn)行矩陣乘法 matrix_a = [[1, 2], [3, 4]] matrix_b = [[5, 6], [7, 8]] result = [[0, 0], [0, 0]] for i in range(len(matrix_a)): for j in range(len(matrix_b[0])): for k in range(len(matrix_b)): result[i][j] += matrix_a[i][k] * matrix_b[k][j] # 推薦:使用numpy進(jìn)行矩陣乘法 matrix_a_np = np.array(matrix_a) matrix_b_np = np.array(matrix_b) result_np = np.dot(matrix_a_np, matrix_b_np) print(result) # 輸出: [[19, 22], [43, 50]] print(result_np) # 輸出: [[19 22] [43 50]]
9. 使用pandas處理數(shù)據(jù)
pandas
是一個(gè)強(qiáng)大的數(shù)據(jù)分析庫,特別適合處理表格數(shù)據(jù)。
示例:
import pandas as pd # 不推薦:使用純Python字典和列表處理數(shù)據(jù) data = {'Name': ['Alice', 'Bob', 'Charlie'], 'Age': [25, 30, 35]} ages = [age for age in data['Age'] if age > 30] # 推薦:使用pandas處理數(shù)據(jù) df = pd.DataFrame(data) filtered_df = df[df['Age'] > 30] print(ages) # 輸出: [35] print(filtered_df) # 輸出: Name Age # 2 Charlie 35
10. 使用multiprocessing進(jìn)行并行處理
如果你的任務(wù)是可以并行化的,那么使用multiprocessing
模塊可以顯著提高性能。
示例:
import multiprocessing def square(x): return x ** 2 # 不推薦:串行處理 results_serial = [square(i) for i in range(10)] # 推薦:并行處理 pool = multiprocessing.Pool() results_parallel = pool.map(square, range(10)) pool.close() pool.join() print(results_serial) # 輸出: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] print(results_parallel) # 輸出: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
11. 使用asyncio進(jìn)行異步編程
對于I/O密集型任務(wù),使用asyncio
可以提高程序的響應(yīng)速度。
示例:
import asyncio async def fetch_data(): await asyncio.sleep(1) return "Data fetched" # 不推薦:同步等待 def sync_fetch(): import time time.sleep(1) return "Data fetched" # 推薦:異步等待 async def main(): result = await fetch_data() print(result) asyncio.run(main()) # 輸出: Data fetched
12. 使用cython編譯Python代碼
cython可以將Python代碼編譯成C代碼,從而提高執(zhí)行速度。
示例:
# 不推薦:純Python代碼 def slow_function(n): return sum(i * i for i in range(n)) # 推薦:使用Cython編譯 # 在文件slow_function.pyx中定義 def fast_function(int n): cdef int i, result = 0 for i in range(n): result += i * i return result # 編譯并導(dǎo)入 from distutils.core import setup from Cython.Build import cythonize setup(ext_modules=cythonize("slow_function.pyx")) from slow_function import fast_function print(slow_function(1000000)) # 較慢 print(fast_function(1000000)) # 較快
13. 使用numba加速數(shù)值計(jì)算
numba
可以通過即時(shí)編譯技術(shù)加速數(shù)值計(jì)算。
示例:
import numba @numba.jit def fast_sum(a, b): return a + b # 不推薦:純Python加法 def slow_sum(a, b): return a + b print(slow_sum(10, 20)) # 輸出: 30 print(fast_sum(10, 20)) # 輸出: 30
14. 使用cProfile進(jìn)行性能分析
在優(yōu)化代碼之前,先使用cProfile
找出瓶頸所在。
示例:
import cProfile def profile_me(): total = 0 for i in range(1000000): total += i return total cProfile.run('profile_me()')
15. 使用line_profiler進(jìn)行逐行分析
line_profiler
可以幫助你找到具體哪一行代碼最耗時(shí)。
示例:
# 安裝line_profiler # pip install line_profiler @profile def function_to_profile(): a = 2 b = 3 c = a + b return c function_to_profile()
實(shí)戰(zhàn)案例:優(yōu)化圖像處理算法
假設(shè)你需要編寫一個(gè)圖像處理程序,將一張圖片轉(zhuǎn)換為灰度圖。我們來看一下如何應(yīng)用上述技巧來優(yōu)化這個(gè)過程。
原始代碼:
from PIL import Image def to_grayscale(image_path): image = Image.open(image_path) width, height = image.size grayscale_image = Image.new('L', (width, height)) for x in range(width): for y in range(height): r, g, b = image.getpixel((x, y)) gray = int(0.299 * r + 0.587 * g + 0.114 * b) grayscale_image.putpixel((x, y), gray) grayscale_image.save('grayscale.jpg') to_grayscale('input.jpg')
優(yōu)化后的代碼:
import numpy as np from PIL import Image def to_grayscale_optimized(image_path): image = Image.open(image_path).convert('RGB') image_array = np.array(image) grayscale_array = np.dot(image_array[..., :3], [0.299, 0.587, 0.114]).astype(np.uint8) grayscale_image = Image.fromarray(grayscale_array, 'L') grayscale_image.save('grayscale.jpg') to_grayscale_optimized('input.jpg')
在這個(gè)實(shí)戰(zhàn)案例中,我們使用了numpy
來進(jìn)行高效的數(shù)組操作,避免了顯式的雙重循環(huán),從而大大提高了程序的運(yùn)行速度。
總結(jié)
本文介紹了15個(gè)讓Python程序飛速運(yùn)行的技巧,包括使用內(nèi)置函數(shù)和庫、列表推導(dǎo)式、生成器表達(dá)式、集合成員檢查、字典映射、局部變量、緩存結(jié)果、numpy
和pandas
庫、并行和異步處理、cython
和numba
編譯、性能分析工具等。通過這些技巧,你可以寫出更高效、更優(yōu)雅的Python代碼。
到此這篇關(guān)于15個(gè)Python運(yùn)行速度優(yōu)化技巧分享的文章就介紹到這了,更多相關(guān)Python優(yōu)化技巧內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
圖文講解選擇排序算法的原理及在Python中的實(shí)現(xiàn)
這篇文章主要介紹了選擇排序的原理及在Python中的實(shí)現(xiàn),選擇排序的時(shí)間復(fù)雜度為О(n²),需要的朋友可以參考下2016-05-05淺談Python從全局與局部變量到裝飾器的相關(guān)知識
今天給大家?guī)淼氖顷P(guān)于Python的相關(guān)知識,文章圍繞著Python從全局與局部變量到裝飾器的相關(guān)知識展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06Python函數(shù)中的函數(shù)(閉包)用法實(shí)例
這篇文章主要介紹了Python函數(shù)中的函數(shù)(閉包)用法,結(jié)合實(shí)例形式分析了Python閉包的定義與使用技巧,需要的朋友可以參考下2016-03-03python 實(shí)現(xiàn)方陣的對角線遍歷示例
今天小編就為大家分享一篇python 實(shí)現(xiàn)方陣的對角線遍歷示例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-11-11python+requests+pytest接口自動(dòng)化的實(shí)現(xiàn)示例
這篇文章主要介紹了python+requests+pytest接口自動(dòng)化的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04Django使用 Bootstrap 樣式修改書籍列表過程解析
這篇文章主要介紹了Django使用 Bootstrap 樣式修改書籍列表過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08Python庫Gym開發(fā)和比較強(qiáng)化學(xué)習(xí)算法使用探究
這篇文章主要介紹了Python庫Gym開發(fā)和比較強(qiáng)化學(xué)習(xí)算法使用探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01