Python代碼在執(zhí)行的時候,會被編譯為Python字節(jié)碼,再由Python虛擬機執(zhí)行Python字節(jié)碼。有時候就我們執(zhí)行python文件的時候會生成一個pyc文件,這個pyc文件即用于存儲Python字節(jié)碼指令,而這些字節(jié)碼是一種類似于匯編指令的中間語言,但是每個字節(jié)碼對應(yīng)的不是機器指令,而是一段C代碼。
而Dis模塊,就是用于查看這些字節(jié)碼的運行軌跡,因此我們可以用Dis模塊判斷兩個函數(shù)的內(nèi)存占用誰會更大,誰會更消耗CPU性能,不僅如此,通過指令,我們還可以知道Python中一些內(nèi)置函數(shù)、變量的取值過程、運行邏輯,對于我們優(yōu)化代碼很有幫助。
下面將通過兩個例子,來介紹Dis模塊的使用。
1.為什么下面第一個函數(shù)比第二個函數(shù)耗得內(nèi)存更少?
一般人是比較難直接看出來的,但是我們使用Dis模塊卻能很容易找到答案:
結(jié)果:
Dis的結(jié)果其實很容易閱讀:
第一列: 對應(yīng)的源代碼行數(shù)。
第二列: 對應(yīng)的內(nèi)存字節(jié)碼的索引位置。
在第一列和第二列之間的 >> 號表示跳轉(zhuǎn)的目標
第三列: 內(nèi)部機器代碼的操作。
第四列: 指令參數(shù)。
第五列: 實際參數(shù)。
兩個函數(shù)的dis分析用*號隔開了,大家可以清晰地看到兩個函數(shù)之間的語句區(qū)別。第二個函數(shù)的字節(jié)碼索引最大到了30,而第一個函數(shù)的字節(jié)碼索引最大僅到了22,因此,第一個函數(shù)耗得內(nèi)存比第二個函數(shù)少。
而且,在第一列和第二列之間的 >> 號表示跳轉(zhuǎn)的目標,大家可以看第二個函數(shù)第四列的 18,表示其跳轉(zhuǎn)到了索引為18的指令,也就是ROT_TWO。第二個函數(shù)的跳轉(zhuǎn)也比第一個函數(shù)多,這也可能導致其在某種特殊情況下的效率可能會比第一個函數(shù)低。
2.為什么Python2中,whil****e True 比 while 1慢?
while 1:
pass
while True:
pass
可以通過在命令中使用dis進行分析:
可以看到,while 1 在第二行是直接JUMP_ABSOLUTE,因此相比于While True 少了LOAD_NAME 和 POP_JUMP_IF_FALSE。這是因為True在Python2中不是一個關(guān)鍵字,而是一個內(nèi)置變量,因此每次Python都會用LOAD_NAME去檢查(POP_JUMP_IF_FALSE)True的值。這就是為什么While True 比while 1慢的原因。
到了Python3,True變成了關(guān)鍵字,就沒有這個問題了:
Python 3 針對 Python 2 做了非常多的替換,這也是為什么它不兼容 Python 2 的原因之一,差別太大了。因此,建議各位初學者直接上手 Python 3 進行學習,而非 Python 2.
希望以上兩個Dis模塊的使用例子能給大家?guī)硪稽c靈感,分析一段Python代碼的深層次性能問題雖然比較費時費力,但是一旦你分析到了深層次的性能原因,將能累積不少深層次的技術(shù)上的知識,寫出更漂亮的代碼。
-
模塊
+關(guān)注
關(guān)注
7文章
2788瀏覽量
50428 -
DIS
+關(guān)注
關(guān)注
0文章
17瀏覽量
16647 -
虛擬機
+關(guān)注
關(guān)注
1文章
966瀏覽量
29376 -
python
+關(guān)注
關(guān)注
56文章
4827瀏覽量
86796
發(fā)布評論請先 登錄
OPA548 DIS是高阻態(tài)還是什么狀態(tài)?
探究python字節(jié)碼
無法閃現(xiàn)開發(fā)SPC560B-Dis
某DIS仿真系統(tǒng)中的計算機生成兵力研究
ARM設(shè)計的DIS采集系統(tǒng)方案

基于ARM的DIS采集系統(tǒng)設(shè)計

LA46 DIS 09911-1_0126聯(lián)想B460 電路圖
基于SPC582B-DIS微控制器的參考設(shè)計

基于SPC560B-DIS微控制器的參考設(shè)計

基于SPC560D-DIS微控制器的參考設(shè)計

python 使用Dis模塊進行代碼性能剖析

評論