C++ STL map/set 查找速度超級慢原因分析

郵件服務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中。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章