Python 程式先編譯為字節碼,再由虛擬機逐條執行。標準庫 dis 模組可將字節碼「反組譯」為人類可讀的助憶符號,幫助我們理解執行細節與效能差異。
# 終端機直接執行
python -m dis your_script.py
# 程式碼中動態檢視
import dis
dis.dis(your_function)
# test_while.py
while 1:
pass
while True:
pass
$ python -m dis test_while.py
2 0 SETUP_LOOP 3 (to 6)
>> 3 JUMP_ABSOLUTE 3
5 6 SETUP_LOOP 10 (to 19)
>> 9 LOAD_NAME 0 (True)
12 POP_JUMP_IF_FALSE 18
while 1:直接 JUMP_ABSOLUTE 無條件跳回,單一指令。while True:每圈需 LOAD_NAME 讀取全域變數 True,再 POP_JUMP_IF_FALSE 判斷,多兩條指令。Python 2 中 True 只是內建變數(甚至可被重新賦值),非關鍵字;Python 3 已將 True 列為關鍵字,兩者字節碼一致,效能差異消失。
def test():
x = 1
if x < 3:
return "yes"
else:
return "no"
import dis
dis.dis(test)
# 輸出含行號、位移、指令、參數、解析後常數
函數物件的 __code__.co_code 為原始位元組序列,可自行解碼:
code_bytes = [ord(c) for c in test.__code__.co_code]
# [100, 1, 0, 125, 0, 0, ...]
# 100 = LOAD_CONST (opcode),後兩字節為參數索引
對照 dis.opname[opcode] 即可得到指令名稱。
@lru_cache、型別提示等是否生效。dis 是 Python 開發者窺探「引擎蓋下」的利器,善用它能寫出更高效、更符合語言機制的程式碼。