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 _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中。

你可能感兴趣的:(cpp,map)