用python做測試實現高性能測試工具(2)—優化代碼
在上一篇中我們通過換python的解析器來優化性能。但離實際需求還很遠。
方案2: 優化代碼
工欲善其事,必先利其器。要優化代碼,必須先找到代碼的瓶頸所在,最土的方法是添加log, 或者print, 調試完成還需要刪除,比較麻煩。python里面也提供了很多profile工具:profile, cProfile, hotshot, pystats, 但這些工具提供的結果可讀性不是很好,不夠直觀的一眼就能看到那個函數或者那一行占用時間最多。 python line_profiler 提供了這樣的功能,可以很直觀的看到哪一行占用的時間最多,可謂“快準狠”,下載地址: http://pythonhosted.org/line_profiler/
安裝完line_profiler后,在C:\Python27\Lib\site-packages 目錄下會有一個kernprof.py,在可能存在瓶頸的函數上添加 @profile, 如以下例子:
@profile def create_msg2(self,H,msg): li = msg.keys() msg_type=li[0] ULR_avps=[] ULR=HDRItem() ULR.cmd=self.dia.dictCOMMANDname2code(self.dia.MSG_TERM[msg_type]) if msg_type[-1]=='A': msg=msg[msg_type] self.dia.setAVPs_by_dic(msg_type,msg,ULR_avps) ULR.appId=H.appId ULR.EndToEnd=H.EndToEnd ULR.HopByHop=H.HopByHop msg=self.dia.createRes(ULR,ULR_avps) else: self.dia.setAVPs(msg_type,msg,ULR_avps) ULR.appId=self.dia.APPID self.dia.initializeHops(ULR) msg=self.dia.createReq(ULR,ULR_avps) return msg |
運行此文件: kernprof.py -l -v D:\project\mp\src\protocols\libdiametermt.py, 得到如下結果。 從這圖中可以很直觀的看到setAVPS方法占用了96.6%的時間,再進一步定位到此函數,再次添加@proflie修飾符(可以一次在多個函數上添加Profile), 可以再進一步看到setAVPS函數中各行代碼的占用時間比。
通過一步步的分析中看到,開源協議庫中,setAVPS的方法中,查找avp的屬性是從一個3000的循環里面查找的,每個AVP都需要循環3000次,一個diameter消息中至少10個avp,每次encoding一個avp需要循環3W次。 我們初始的解決方法是刪除了很多我們性能測試中用不到的avp(沒辦法,測試開發資源有限,很多時候沒有很好的設計,先做出滿足需求的東西再說。), 但也只是提高到了150左右,離需求還差的很遠。所以我們把AVP都改成了字典方式,可以根據名字快速查找到AVP的屬性。
除了代碼的優化,同時還增加了encoding avp的線程數,后面章節將會講到多線程和多進程,對性能的影響。
相關文章: