前言:最近很長一段時間沒有更新部落格了,忙於一堆子專案的開發,嚴重拖慢了學習與思考的程序。在python裡,這很容易實現,借助裝飾器,在每個方法的首尾加入計時計數就好了。為此我寫了個monitor模組,裡面有register裝飾器和report方法,分別用於註冊乙個要監控的方法、匯出監測結果。開水倒滿了需要提早放下杯子,晚了就會燙手,這段時間以來,寫的東西越來越不嚴謹,各種低階錯誤頻出,早該停下總結並鞏固一下了。
但出於一些原因一直沒付諸於行,終於,燙到手了
具體的**很簡單,這裡就不貼上了,主要說明一下,report匯出的結果形如:
}
其中funcname為監控的方法名,count為該方法呼叫次數,time為該方法總耗時,注意是總耗時,不是每一次的平均耗時。
接下來,我在overview介面的函式返回前,列印monitor.report()
,再用@monitor.register
註冊方法內呼叫的一些可能耗時的函式或方法,這樣我就得到了乙份反映方法呼叫次數及耗時的日誌
附件:monitor模組
在對主要用到的可能耗時的方法|函式監控後,根據輸出的結果,這個方法平均耗時140多秒。
}
get_team_dict(team)
函式主要做的是,將從資料庫取得的team物件(team表對應的orm類team的物件),轉化為乙個dict。
這個方法內有兩個主要的操作,乙個是這6s是訪問資料庫造成的。如你所見,這裡是可以優化的,把team與area做成乙個view,就可以省去team.area()時查詢資料庫的消耗。team.area()
,獲取這個team物件對應的地點物件(area表對應的orm類area的物件)。這一步耗時大約6s}
但一方面,這個資料是在我開發用的pc上進行統計的,相當於在訪問遠端資料庫,考慮網路延時,效率其實遠遠低於實際生產環境。在這種情況下,花費時間對這種細節調優並不會帶來太大好處。
我的意思是說現在造成效能瓶頸的主要原因不是它,應該優先去處理更重要的地方,這種細節還是要注意的,最好是在設計之初就把team與area繫結成relationship。
另乙個是那麼接下來要做的就是對這個方法進一步拆解了,類似以上步驟,經過一些列拆解分析,最終發現造成延時的最內層方法是它:team.analyze()
方法,也是任務量最大的方法,需要統計團隊的各項資訊,}
footprint.get_pics()
def
get_pics
(self, url_root='/', style='@!preview'):
"""獲取url列表"""
from main.config import get_config
ali_conf = get_config()['ali']
util = ossutil(
ali_conf['key'], ali_conf['secret'],
ali_conf['bucket'], ali_conf['endpoint']
)return [
for image in util.iter_directory(self.pics_dir)
]
方法內的匯入時為了解決回環匯入問題,但顯然這不是很好的解決辦法,雖然影響也不大。後來優化掉了咦?內層不是還有方法嗎?為什麼不繼續向內統計了呢?
答案是,我*也想啊,但就在這裡出問題了,拆不下去了!!!
到底發生了什麼呢?請看這份統計:
,
"temp_get_image_dict": ,
"get_config": ,
"temp_url_for_get_image": ,
"__init__": ,
"iter_directory": ,
"temp_get_ali_conf":
}
告訴我你看到了什麼?是的,get_pics()
方法耗時405s,其實是100多s
(這麼說的原因是,由於開始時monitor模組沒考慮到多次統計的清空問題,導致累加了4次)
而get_pics()
方法內部的幾個方法總耗時加起來卻遠遠低於這個值!
帶有這就是為什麼到了temp_
字首的函式是為了方便統計而從get_pics
中拆出來的,根據命名大概也能猜出來原來是啥吧,比如
temp_get_image_dict()
函式對應著原先的return [{} for each in range]
中的{}
部分
get_pics()
後就拆不下去了,某個方法本身耗時100多s,其內部依次呼叫了幾個函式,而這些函式總耗時加起來居然遠低於方法本身,怎麼可能!
好吧,這回真是頭大了,有史以來第一次對自己的程式設計能力產生了懷疑,這太可怕了!
上一章說,「下面的內容是重點」,但很遺憾,現在還沒到重點,或許有點囉嗦了?嘛,「下面的內容」範圍很廣的,下一章、下兩章,區別不是很大嘛~~~
就這樣,或許在我下一章之前,你就已經意識到問題發生在哪兒了?明天見
一次優化經歷
問題 excel資料匯入,儲存到資料庫中,為了優化查詢效率和其他一些業務需求,需要將資料的一列屬性切分後儲存到redis中,插入資料庫前要保證其中乙個屬性不重複,另外乙個屬性已經在資料庫中。為了將問題描述簡單些,我們假設excel中有兩列資料a和b,其中資料a要保證資料庫中不重複,資料b保證資料庫中...
一次優化記錄
備註 由於隱私 部分使用了偽 偽sql 直接查十點查全部 select from 使用者優惠券表 where 優惠券id in select id from 優惠券表 where 限制 新使用者 and 90天內 總時間40 秒 這裡用exlpain分析 優惠券id是有索引的,但是實際上沒有走索引。...
一次優化記錄
今天收到乙個同事的求助,說有乙個sql跑了乙個多小時沒有結果。我看了看,這個sql是這樣的 隱藏了敏感資訊 select 號碼,列2,列3,max starttime flag from 表1 t1 where flag 0 and 號碼 not in select 號碼 from 表2 t2 gr...