用python做測試實現(xiàn)高性能測試工具(2)—優(yōu)化代碼
在上一篇中我們通過換python的解析器來優(yōu)化性能。但離實際需求還很遠。
方案2: 優(yōu)化代碼
工欲善其事,必先利其器。要優(yōu)化代碼,必須先找到代碼的瓶頸所在,最土的方法是添加log, 或者print, 調(diào)試完成還需要刪除,比較麻煩。python里面也提供了很多profile工具:profile, cProfile, hotshot, pystats, 但這些工具提供的結(jié)果可讀性不是很好,不夠直觀的一眼就能看到那個函數(shù)或者那一行占用時間最多。 python line_profiler 提供了這樣的功能,可以很直觀的看到哪一行占用的時間最多,可謂“快準狠”,下載地址: http://pythonhosted.org/line_profiler/
安裝完line_profiler后,在C:\Python27\Lib\site-packages 目錄下會有一個kernprof.py,在可能存在瓶頸的函數(shù)上添加 @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, 得到如下結(jié)果。 從這圖中可以很直觀的看到setAVPS方法占用了96.6%的時間,再進一步定位到此函數(shù),再次添加@proflie修飾符(可以一次在多個函數(shù)上添加Profile), 可以再進一步看到setAVPS函數(shù)中各行代碼的占用時間比。
通過一步步的分析中看到,開源協(xié)議庫中,setAVPS的方法中,查找avp的屬性是從一個3000的循環(huán)里面查找的,每個AVP都需要循環(huán)3000次,一個diameter消息中至少10個avp,每次encoding一個avp需要循環(huán)3W次。 我們初始的解決方法是刪除了很多我們性能測試中用不到的avp(沒辦法,測試開發(fā)資源有限,很多時候沒有很好的設(shè)計,先做出滿足需求的東西再說。), 但也只是提高到了150左右,離需求還差的很遠。所以我們把AVP都改成了字典方式,可以根據(jù)名字快速查找到AVP的屬性。
除了代碼的優(yōu)化,同時還增加了encoding avp的線程數(shù),后面章節(jié)將會講到多線程和多進程,對性能的影響。
相關(guān)文章: