使用內置數據類型
內置數據類型非常快,尤其是與我們自定義的類型相比。
這主要是因為內置的數據類型是由 C 實現的,而在 Python 中寫的代碼運行速度實在無法與之相比。
盡量使用內置函數,去掉屬性訪問
import math import time def func(): lst = [] for i in range(1, 10000000): lst.append(math.sqrt(i)) # 直接調用 sqrt return lst start = time.time() lst = func() end = time.time() print(end-start)
運行時間:4.470336198806763秒
from math import sqrt # 直接引用特定函數或屬性 import time def func(): lst = [] for i in range(1, 10000000): lst.append(sqrt(i)) # 直接調用 sqrt return lst start = time.time() lst = func() end = time.time() print(end-start)
運行時間:3.7398300170898438秒
因為在進行屬性訪問的時候啊,會調用這個對象的 __getattribute__ 或者 __getattr__ 方法,造成了額外的開銷,所以導致速度變慢。
使用生成器,例如列表推導式
from math import sqrt import time def func(): # for 循環改為列表推導式 lst = [sqrt(i) for i in range(1, 10000000)] return lst start = time.time() lst = func() end = time.time() print(end-start)
列表推導式內的迭代是 C 實現的,所以效率更高。
使用 lru_cache 緩存或持久化
參考:https://www.cnblogs.com/-wenli/p/11441142.html
盡量使用本地變量
程序運行速度與在每個作用域中查找變量有關。
實際上,訪問不同作用域的變量速度也是不同的,比如在函數內訪問本地變量(最快),訪問類層面變量(如 self.name,比較慢),以及全局變量,比如例子中導入的函數 time.time (這種最慢)。
使用numba
介紹
Numba是Python的即時編譯器,它最適用於使用NumPy數組和函數以及循環的代碼。使用Numba的最常用方法是通過其裝飾器集合,可以應用於您的函數來指示Numba編譯它們。當調用Numba修飾函數時,它被編譯為機器代碼“及時”執行,並且您的全部或部分代碼隨后可以以本機機器代碼速度運行!
什么樣的代碼會被加速?
代碼中的數學運算、NumPy或者循環,兼容常用的科學計算包,如numpy、cmath等。
怎么使用?
只需要添加兩行代碼
導入及使用語法糖
import numba as nb import numpy as np import time @nb.jit(nopython=True) def nb_sum(): arr = [] for i in range(10000000): arr.append(i) def py_sum(): arr = [] for i in range(10000000): arr.append(i) start = time.time() nb_sum() end = time.time() print("numba加速的函數運行時間: %s" % (end - start)) start = time.time() py_sum() end = time.time() print("沒加速的函數運行時間: %s" % (end - start))
工作原理
Numba讀取裝飾函數的Python字節碼,並將其與有關函數輸入參數類型的信息相結合。
它分析並優化您的代碼,最后使用LLVM編譯器庫生成函數的機器代碼版本,根據您的CPU功能量身定制。
每次調用函數時都會使用此編譯版本。
