郵件服務CPU飆升至100%
有天,運營人員反饋說,玩家郵件處理異常,查看郵件服務,發現CPU已經100%,但是仔細查看了一下代碼,感覺並無異常。經過一段時間的分析研究,終於找到一個時間消耗比較久的函數。
代碼
bool checkUserAlreadAddMail(int user_id, time_t create_time) {
auto iter = _map_user_list.find(create_time);
if (iter != _map_user_list.end()) {
auto user_list = iter->second;
auto user_iter = user_list.find(user_id);
if (user_iter != user_list.end()) {
//找到了,已經添加
return true;
}
}
return false;
}
邏輯比較簡單,就是判斷一封郵件是否給user_id正常添加過
map<time_t, set > _map_user_lit爲數據類型
可是爲何該函數消耗時間會很多呢,實際測試結果是當set中的元素在200w時,該函數消耗的時間在0.2-0.3s之間
這顯然超越了我們的認知啊?Why?不是說好了set和map的查找速度是logN嗎?爲什麼這麼慢?
經過一段時間的研究才發現,bug就出在auto user_list = iter->second;這一段上面,由於習慣了C++11,讓我們已經完全忘記了,這裏是拷貝,並不是引用,是拷貝導致了大量的時間消耗,從而導致出現嚴重的性能問題,並不是查找耗時。所以一開始,就將方向搞錯了,導致定位問題花費了比較長的時間
總結
- map/set的查找速度logN,一般的情況下,查找性能都不會有問題,不要懷疑;
- 在寫代碼的時候,一定要注意什麼地方是拷貝,什麼地方是引用;
- 編碼規範需要平時養成,上面的案例中其實完全沒有必要在此重新去聲明一個user_list中。