最近寫(抄)了一支利用dlib做臉部辨識的工具,但是效能不佳,程式執行需要大約一分鐘的準備時間,然後FPS也是沒辦法超過1,我用VSCode的F5 debug工具,從第一行逐行執行,發現是卡在cap = cv2.VideoCapture(0)這句,竟然可以卡40秒,後來查詢網路說可以加上cv2.CAP_DSHOW,但是只能用在Windows系統,樹莓派沒辦法使用,不過畢竟是開啟時一次的執行時間,影響不大所以就暫時先不處理。

另外一個比較嚴重的問題是fps,640x480解析度下的fps大約0.5-0.9之間,如果改成320x240可以超過1,實在是慢的離譜,實在很想了解問題出在什麼地方,是哪一行造成的瓶頸,雖然我還是可以用debug逐行執行來"感受"一下時間,但是像這種無限迴圈,要自己一直按F10想想實在算了。

想起我以前在VS.net開發工具時,在debug時會計算每行的執行時間,例如下圖,當從上一行執行到這行時,一共花費了0.979秒,如果我們一步一步Step就可以了解每行的狀況,知道瓶頸出在哪裡,不過這也太累了。

image

使用debug工具來了解執行效能其實還有一個問題,就是也許他這次很慢,但下次就會很快,例如網路擁塞,每次需要的時間不太一樣,因此必須長期評估再"平均"計算比較合理,用debug工具做這件事情實在很沒有效率。

在論壇詢問一下,網友提供了幾個工具,最知名應該是這個
Scalene:https://github.com/plasma-umass/scalene
這款的優點是設定很簡單,只要兩個步驟

1.    安裝套件:
pip3 install scalene
2.    利用scalene來執行你的Python程式:
scalene YourCode.py
當程式執行完畢後,就會自己跳出這個執行報告,非常詳細,包括每行的執行「總」時間、使用多少GPU、記憶體等等的報告。

image

不過我發現一個問題,這個套件提供的是執行「總」時間,但假如我是一個迴圈,那麼特定幾行就可能會執行很多次,而這裡顯示’總’時間而不是’平均’時間,像我這個報告第41行看起來雖然花費時間最多,但這也是因為他被重複執行多次的總和,自然累積會比較高,就無法確認fps慢是不是這行造成的,因此這個套件並沒有解決我的問題。(不過也可能只是我不知道要怎麼使用這個套件?)

網路找一下關鍵字「profiler」,發現另外一個工具「line_profiler」
line_profiler:https://github.com/rkern/line_profiler

優點也是逐行評估,但是卻會顯示每行被執行的次數,以及總時間、平均時間等等的,不過執行上卻較為麻煩,因為line_profiler是評估副程式的,在要評估的副程式前加上「@profile」,他就會單獨評估這個副程式,但那如果我們要評估整個程式該怎麼辦?很簡單,我是把整個程式都搬到一個副程式內即可。

這裡說明一下步驟
1.    安裝套件:
pip install line_profiler
2.    引入套件:在python程式最上方import
from line_profiler import LineProfiler
3.    加入關鍵字:在要評估的副程式前加上
@profile
def function():
    ….
    ….
4.    執行語法:
kernprof -l -v YourCode.py
當程式執行完畢後,會產生一個報告檔名稱為「YourCode.py.lprof」,以及主動跳出文字模式的報告,但如果事後需要再開啟報告,可以使用以下語法
5.    叫出報告:
python -m line_profiler YourCode.py.lprof

報告部份節錄如下:

image

這裡我們可以看到,他會列出每行程式碼被執行的Line(程式行號)、次數(Hits)、Time(總時間)、Per Hit(平均時間)、%Time(佔用執行總時間的比例)。
依據此報告可以發現,這個程式的第47行被執行10次,花費總時間為5.149秒,所以平均約為0.5秒,佔這個程式總時間的約10%左右,這樣我就知道問題出在什麼地方了。

這個工具是不是很棒呢?雖然沒有圖形界面的報告,但是非常符合我的需求,因此把使用方法介紹給大家。
 

 

arrow
arrow

    夜市 小霸王 發表在 痞客邦 留言(0) 人氣()