透過一次GC調整使Python速度提高20%

banq發表於2022-11-24

Python有兩種型別的記憶體管理:
  • 主要是引用計數。物件會跟蹤指向它們的變數的數量。如果這個數字達到了0,它們就會被立即刪除,而且是確定性的。在沒有統計資料支援的情況下,我猜測99.9%以上的記憶體是這樣處理的。
  • 0.1%:這裡失敗的一個案例是如果你有一個迴圈(想想有配偶欄位的 Person 物件)。輸入垃圾收集 .它偶爾會執行,尋找遺漏的參考計數清理。

引用計數很好,但GC,它執行得太頻繁了。
觸發因素是當你分配的700個或更多的容器物件(類、資料集、圖元、列表等)超過已清理的數量時,會執行一個GC迴圈。
例如,當你做一個查詢:

recent = await PageHits.objects().filter(date >= today).to_list()


如果該查詢中有接近 700 個結果,那麼您甚至在獲得完整列表之前就已經達到了 GC 週期。
我們在Talk Python Training上的站點地圖僅載入頁面就產生了 77 個 GC 週期,77!

training.talkpython.fm/sitemap.xml

但你可以改變它。
在應用程式啟動時嘗試此程式碼:

# clean up what might be garbage so far.
gc.collect(2)
# Exclude current items from future GC.
gc.freeze()

allocs, gen1, gen2 = gc.get_threshold()
allocs = 50_000  # Start the GC sequence every 50K not 700 allocations.
gen1 = gen1 * 2
gen2 = gen2 * 2
gc.set_threshold(allocs, gen1, gen2)


在 Talk Python 上,我們看到整體速度提高了 20%,而記憶體使用沒有變化。

關於這種改進對於實際工作負載的現實性存在一些爭論。
這篇文章引起了相當多的討論。您可以在 Mastodon 執行緒上看到它。
 

相關文章