python 效能提升的幾種方法
關於python 性能提升的一些方案。
一、函數呼叫最佳化(空間跨度,避免存取記憶體)
程式的最佳化核心點在於盡量減少操作跨度,包括程式碼執行時間上的跨度以及記憶體中空間跨度。
1.大數據求和,使用sum
a = range(100000) %timeit -n 10 sum(a) 10 loops, best of 3: 3.15 ms per loop %%timeit ...: s = 0 ...: for i in a: ...: s += i ...: 100 loops, best of 3: 6.93 ms per loop
2.小數據求和,避免使用sum
%timeit -n 1000 s = a + b + c + d + e + f + g + h + i + j + k # 数据量较小时直接累加更快 1000 loops, best of 3: 571 ns per loop %timeit -n 1000 s = sum([a,b,c,d,e,f,g,h,i,j,k]) # 小数据量调用 sum 函数,空间效率降低 1000 loops, best of 3: 669 ns per loop
結論:大數據求和sum效率高,小數據求和直接累加效率高。
二、for循環最佳化之取元素(使用堆疊或暫存器,避免存取記憶體)
for lst in [(1, 2, 3), (4, 5, 6)]: # lst 索引需要额外开销 pass
應盡量避免使用索引。
for a, b, c in [(1, 2, 3), (4, 5, 6)]: # better pass
相當於給每一個元素直接賦值。
def force(): lst = range(4) for a1 in [1, 2]: for a2 in lst: for a3 in lst: for b1 in lst: for b2 in lst: for b3 in lst: for c1 in lst: for c2 in lst: for c3 in lst: for d1 in lst: yield (a1, a2, a3, b1, b2, b3, c1, c2, c3, d1) %%timeit -n 10 for t in force(): sum([t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7], t[8], t[9]]) 10 loops, best of 3: 465 ms per loop %%timeit -n 10 for a1, a2, a3, b1, b2, b3, c1, c2, c3, d1 in force(): sum([a1, a2, a3, b1, b2, b3, c1, c2, c3, d1]) 10 loops, best of 3: 360 ms per loop
三、生成器最佳化(查表代替運算)
def force(start, end): # 用于密码暴力破解程序 for i in range(start, end): now = i sublst = [] for j in range(10): sublst.append(i % 10) # 除法运算开销较大,比乘法大 i //= 10 sublst.reverse() yield(tuple(sublst), now)
def force(): # better lst = range(5) for a1 in [1]: for a2 in lst: for a3 in lst: for b1 in lst: for b2 in lst: for b3 in lst: for c1 in lst: for c2 in lst: for c3 in lst: for d1 in lst: yield (a1, a2, a3, b1, b2, b3, c1, c2, c3, d1)
r0 = [1, 2] # 可读性与灵活性 r1 = range(10) r2 = r3 = r4 = r5 = r6 = r7 = r8 = r9 = r1 force = ((a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) for a0 in r0 for a1 in r1 for a2 in r2 for a3 in r3 for a4 in r4 for a5 in r5 for a6 in r6 for a7 in r7 for a8 in r8 for a9 in r9)
四、冪運算最佳化(pow(x,y,z))
def isprime(n): if n & 1 == 0: return False k, q = find_kq(n) a = randint(1, n - 1) if pow(a, q, n) == 1: # 比使用 a ** q % n 运算优化数倍 return True for j in range(k): if pow(a, pow(2, j) * q, n) == n - 1: # a **((2 ** j) * q) % n return True return False
結論:pow(x,y,z)優於x**y%z.
五、除法運算最佳化
In [1]: from random import getrandbits In [2]: x = getrandbits(4096) In [3]: y = getrandbits(2048) In [4]: %timeit -n 10000 q, r = divmod(x, y) 10000 loops, best of 3: 10.7 us per loop In [5]: %timeit -n 10000 q, r = x//y, x % y 10000 loops, best of 3: 21.2 us per loop
結論:divmod優於//和%。
六、最佳化演算法時間複雜度
演算法的時間複雜度對程式的執行效率影響最大,在python中可以選擇適當的資料結構來最佳化時間複雜度,如list和set找出某一個元素的時間複雜度分別是O(n)和O( 1)。不同場景有不同的最佳化方式,總的來說,一般有分治,分支定界、貪心動態規劃等思想。
七、合理使用copy和deepcopy
對於dict和list等資料結構的對象,直接賦值使用的是引用的方式。而有些情況下需要複製整個對象,這時可以使用copy包裡的copy和deepcopy,這兩個函數的不同之處在於deepcopy是遞歸複製的。效率不同:
In [23]: import copy In [24]: %timeit -n 10 copy.copy(a) 10 loops, best of 3: 606 ns per loop In [25]: %timeit -n 10 copy.deepcopy(a) 10 loops, best of 3: 1.17 us per loop
timeit後面的-n表示運行的次數,後兩行對應的是兩個timeit的輸出,下同。由此可見後者慢一個數量級。
關於copy的例子:
>>> lists = [[]] * 3 >>> lists [[], [], []] >>> lists[0].append(3) >>> lists [[3], [3], [3]]
發生的事情是這樣的,[[]]是包含一個空列表的只有一個元素的列表,所以[[]] * 3的所有三個元素都是(指向)這個空列表。修改lists的任何元素都修改這個清單。修改效率高。
八、使用dict或set找出元素
python 字典和集合都是使用hash表來實作(類似c++標準函式庫unordered_map),而找出元素的時間複雜度是O(1)。
In [1]: r = range(10**7) In [2]: s = set(r) # 占用 588MB 内存 In [3]: d = dict((i, 1) for i in r) # 占用 716MB 内存 In [4]: %timeit -n 10000 (10**7) - 1 in r 10000 loops, best of 3: 291 ns per loop In [5]: %timeit -n 10000 (10**7) - 1 in s 10000 loops, best of 3: 121 ns per loop In [6]: %timeit -n 10000 (10**7) - 1 in d 10000 loops, best of 3: 111 ns per loop
結論:set 的記憶體佔用量最小,dict運行時間最短。
九、合理使用(generator)和yield(節省記憶體)
In [1]: %timeit -n 10 a = (i for i in range(10**7)) # 生成器通常遍历更高效 10 loops, best of 3: 933 ns per loop In [2]: %timeit -n 10 a = [i for i in range(10**7)] 10 loops, best of 3: 916 ms per loop In [1]: %timeit -n 10 for x in (i for i in range(10**7)): pass 10 loops, best of 3: 749 ms per loop In [2]: %timeit -n 10 for x in [i for i in range(10**7)]: pass 10 loops, best of 3: 1.05 s per loop
結論:盡量使用生成器去遍歷。
以上就是對python 性能提升的一些方案,後續繼續補充,需要的可以看下。

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

PHP適合網頁開發和快速原型開發,Python適用於數據科學和機器學習。 1.PHP用於動態網頁開發,語法簡單,適合快速開發。 2.Python語法簡潔,適用於多領域,庫生態系統強大。

在 Sublime Text 中運行 Python 代碼,需先安裝 Python 插件,再創建 .py 文件並編寫代碼,最後按 Ctrl B 運行代碼,輸出會在控制台中顯示。

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

PHP起源於1994年,由RasmusLerdorf開發,最初用於跟踪網站訪問者,逐漸演變為服務器端腳本語言,廣泛應用於網頁開發。 Python由GuidovanRossum於1980年代末開發,1991年首次發布,強調代碼可讀性和簡潔性,適用於科學計算、數據分析等領域。

Golang在性能和可擴展性方面優於Python。 1)Golang的編譯型特性和高效並發模型使其在高並發場景下表現出色。 2)Python作為解釋型語言,執行速度較慢,但通過工具如Cython可優化性能。

在 Visual Studio Code(VSCode)中編寫代碼簡單易行,只需安裝 VSCode、創建項目、選擇語言、創建文件、編寫代碼、保存並運行即可。 VSCode 的優點包括跨平台、免費開源、強大功能、擴展豐富,以及輕量快速。

在 Notepad 中運行 Python 代碼需要安裝 Python 可執行文件和 NppExec 插件。安裝 Python 並為其添加 PATH 後,在 NppExec 插件中配置命令為“python”、參數為“{CURRENT_DIRECTORY}{FILE_NAME}”,即可在 Notepad 中通過快捷鍵“F6”運行 Python 代碼。
