載入速度提升 15%,關於 Python 啟動加速探索與實踐的解析 | 龍蜥技術
編者按:在剛剛結束的 PyCon China 2022 大會上,龍蜥社群開發者嚴懿宸分享了主題為《Python 啟動加速的探索與實踐》的技術演講。本次演講,作者將從 CPython 社群相關工作、本方案的設計及實現,以及業務層面的整合等方面進行介紹。
以下為本次演講內容:
一、Python 啟動速度簡析
首先從一個 Python 3 中空直譯器啟動時間的好事分析開始。我們可以看到,主要的耗時都和 Python 包載入有關。
其中,CPU 時間中包載入佔據了 30% 左右的時間;而 37% 的等待時間中,磁碟 IO 等花費的時間也和包載入有較大的關聯。
熟悉 Python 機制的朋友大概知道,Python 中載入一個包首先會搜尋對應的 pyc 檔案,這是一種序列化的位元組碼格式。找到之後會對其進行反序列化,並執行其中的程式碼。如對應的 pyc 檔案不存在,會重新編譯 py 檔案得到位元組碼,並序列化為 pyc 檔案持久化儲存。我們最佳化的主要目標主要集中在載入包這個過程,希望能夠至少免去每次查詢、讀取、反序列化的開銷。
以 Python3.10 為例,這裡是使用 python 直譯器啟動一個空語句的所需時間,同時使用了 -Ximporttime 列印出過程中載入每一個包的耗時。可以粗略地看到,包載入時間大約佔了總時間的 30% 左右。我們發現這種情況和 Java 虛擬機器類似。在 Java 中,Java 會首先將 Java 原始碼編譯為 Java 位元組碼,隨後由 Java 命令執行。
我們知道 Java 的優勢並不包括啟動速度,這種流程也是原因之一。那麼 Java 如何部分解決這個問題呢?
二、PyCDS (程式碼物件共享)設計與實現
Java 中有一個叫做 CDS/AppCDS 的機制,透過將 Java 位元組碼和一些輔助資料持久化儲存,在後續啟動時使用 mmap 載入,節約了磁碟 IO 和解析驗證 class 檔案的開銷。
很自然的想法是,如果我們希望在 Python 中使用類似的技術,目標應該是 Python 位元組碼。
Python 預設從 py 檔案匯入模組的邏輯如上圖左邊所示,首先根據制定的名字獲取對應的規則,隨後嘗試尋找 pyc 檔案或重新編譯。最後,使用 exec 命令利用程式碼和一個空 dict 來建立模組,並加入 runtime。
我們做的事情可以簡化為右側邏輯。同樣根據包名,嘗試從 mmap 中載入。如果成功,那麼同樣的 codeobject 也可以用於初始化。
這樣做有什麼直接的障礙?
可以看到,Python 中程式碼物件的 C 資料結構大致如圖,包括 consts、string、bytes 等 Python 資料型別。
以使用到的 codeobject 作為 root,將涉及的資料序列化儲存到記憶體對映中。
在這一步,最直接的問題是記憶體隨機化機制。在處理 code object 中的 Python 物件時,每個 Python 物件頭中都儲存著指向當前程式中對應型別資訊的指標。Runtime 透過這個指標判斷該物件在 Python 中的型別。
以 PyCode_Type 為例,如果不做處理,這裡會丟失型別資訊(紅色 offset)。
為了解決這個問題,在我們建立的映象檔案中會儲存涉及的物件指標。在載入時動態 patch 相關的指標。
在整個過程中涉及的 Python 型別包括:
-
常量(bool/None/ellipsis)
-
字面量(float/complex)
-
需要額外分配的變數(long/bytes/str)
-
container(tuple/frozenset)
對於常量和字面量,在記憶體對映中分配好空間後直接賦值即可儲存;對於後兩種,需要模擬 Python 中變數初始化的邏輯,建立合適的記憶體大小並寫入對應位置。同時,對於非常量的型別,還需要對記憶體對映中的引用計數額外賦值,防止意外觸發 Python 中的回收。
以上就是本專案的大致內容,另外關於專案的具體用法請前往 PyCDS 專案主頁或我們在 龍蜥實驗室上的課程檢視,連結見下:
龍蜥實驗室課程:lab.openanolis.cn/#/apply/chapters?courseId=117
PyCDS 主頁:github.com/alibaba/code-data-share-for-python
—— 完 ——
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70004278/viewspace-2929129/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 效能提升 57% ,SMC-R 透明加速 TCP 實戰解析 | 龍蜥技術TCP
- 螞蟻安全科技 Nydus 與 Dragonfly 映象加速實踐 | 龍蜥技術Go
- 基於 Coolbpf 的應用可觀測實踐 | 龍蜥技術
- 技術門檻高?來看 Intel 機密計算技術在龍蜥社群的實踐 | 龍蜥技術Intel
- 龍蜥開源核心追蹤利器 Surftrace:協議包解析效率提升 10 倍! | 龍蜥技術協議
- Inspur KOS 龍蜥衍生版面向智慧新媒體轉型的探索與實踐 | 龍蜥案例
- 虛擬化解決方案 virtio 的技術趨勢與 DPU 實踐解讀 | 龍蜥技術
- 跨語言程式設計的探索 | 龍蜥技術程式設計
- 技術解讀:Dragonfly 基於 P2P 的智慧映象加速系統 | 龍蜥技術Go
- 入門即享受!coolbpf 硬核提升 BPF 開發效率 | 龍蜥技術
- 簡單、透明、安全、高度整合!龍蜥可信 SBOM 能力探索與實踐
- laravel開啟opcache提升載入速度Laravelopcache
- 助力Koordinator雲原生單機混部,龍蜥混部技術提升CPU利用率達60%|龍蜥技術
- 雲原生技術領域的探索與實踐
- 關於Python中math 和 decimal 模組的解析與實踐PythonDecimal
- vivo直播應用技術實踐與探索
- 大眾點評搜尋相關性技術探索與實踐
- 萬里資料庫加入龍蜥社群,打造基於“龍蜥+GreatSQL”的開源技術底座資料庫SQL
- 高德技術團隊:深度學習在導航速度預測中的探索與實踐深度學習
- SysOM 案例解析:消失的記憶體都去哪了 !| 龍蜥技術記憶體
- 【效能優化實踐】優化打包策略提升頁面載入速度優化
- WEB站點效能優化實踐(載入速度提升2s)Web優化
- 《可信計算技術最 佳實踐白皮書》釋出,龍蜥助力可信計算技術應用推廣(可下載)
- 龍蜥社群聯合浪潮資訊釋出《eBPF技術實踐白皮書》(附下載連結)eBPF
- 視訊通訊關鍵技術探索及實踐
- Docker容器編排技術解析與實踐Docker
- B站在實時音影片技術領域的探索與實踐
- 宜信OCR技術探索之版面分析業務實踐|技術沙龍直播速記
- 宜信OCR技術探索與實踐|直播速記
- 中國銀行雲原生技術探索與實踐
- 致敬 hacker :盤點記憶體虛擬化探索之路|龍蜥技術記憶體
- 龍蜥開源Plugsched:首次實現 Linux kernel 排程器熱升級 | 龍蜥技術Linux
- 網站開啟速度慢應該怎麼提升載入速度?網站
- 大資料開發的儲存技術探索與實踐大資料
- 從編譯到可執行,eBPF 加速容器網路的原理分析 | 龍蜥技術編譯eBPF
- 技術沙龍|京東雲DevOps自動化運維技術實踐dev運維
- 最火的容器技術|Docker入門與實踐Docker
- 系統效能提升利刃 | 快取技術使用的實踐與思考快取