stl中unordered_map的insert/clear 性能问题解决

来源:互联网 发布:csbte源码 编辑:程序博客网 时间:2024/05/21 04:23

最近项目中使用到stl unordermap,当map存储的key数量上升到10的6次-7次甚至8次以上时,unordermap的insert接口性能有严重瓶颈

下面是测试代码:

int main() {    std::unordered_map<int, int> t;    for (int i = 0; i <= 10000000; ++i) {    t.insert(make_pair(i, 1));    }}
以上 运行时间

real    0m5.231suser    0m4.888ssys     0m0.331s

原因是随着插入元素增多,insert过程中发生了碰撞,碰撞开链到一定的阈值,触发了增加bucket,进而触发了rehash,打印bucket_size可以看到bucketsize一直在增加,代价非常大

unorderedmap提供了reserve和rehash两个接口

reserve可以用来预留元素个数,rehash根据提供的元素个数预留足够的bucket数目

修改后代码

int main() {    std::unordered_map<int, int> t;    t.reserve(10000000);    t.rehash(10000000);    for (int i = 0; i <= 10000000; ++i) {        t.insert(make_pair(i, 1));    }}

运行时间如下:

real    0m3.823suser    0m3.551ssys     0m0.262s

有很大的好转。

另外,map大了,带来的问题就是clear非常耗时,上面的map clear一次,大约在300ms

将clear换成如下代码:

std::unordered_map<int, int> tmp;t.swap(tmp);

时间马上降到微秒级别

Exchanges the contents of the container with those of other. Does not invoke any move, copy, or swap operations on individual elements
上面是对swap的说明

swap的时间复杂度是常数,根据说明,可以看出应该是底层内存指针的交换

Removes all elements from the container.Invalidates any references, pointers, or iterators referring to contained elements. May also invalidate past-the-end iterators.
上面是对clear的说明,可以看出其时间复杂度是线性的,随元素个数变化,个数多了,挨个销毁,自然就慢了


以上。



0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 leep刀后hpv还是阳性怎么办 结肠息肉钳除后怎么办 痔疮手术后排便困难怎么办 住院未结账跑了怎么办 来月经痔疮犯了怎么办 安保压不下宫缩怎么办 肛周脓肿术后假性愈合怎么办 肛门的皱褶肿了怎么办 1月婴儿排便困难怎么办 吃完辣的痔疮肿了怎么办 肛裂怎么办兰州来医博.相信 胎儿脐带绕颈一周怎么办 郑大一附院怎么办合作医疗 痔疮包不消怎么办很疼 痔疮内扎手术后直肠窄小怎么办 2个月大的宝宝鼻塞怎么办 宝宝鼻屎比较深怎么办 来例假痔疮犯了怎么办 微医爽约过一次怎么办 炸完的薯条软了怎么办 学信网号码换了怎么办 学信网注册换手机了怎么办 学信网手机号码已被注册怎么办 学信网手机号码被注册了怎么办 去英国留学不会做饭怎么办 小米陶瓷刀钝了怎么办 橱柜的缝擦不到怎么办 悠悠球上油早了怎么办 买了没有esp的车怎么办 饥荒海难狗来了怎么办 饥荒海难拖网掉水里了怎么办 饥荒遇到了猪人怎么办 饥荒龙蝇赖在家不走怎么办 饥荒海难崩档了怎么办 gta5全是rpf文件怎么办 饥荒没有海象人营地怎么办 饥荒海滩猎犬来了怎么办 宝宝换牙门牙上长颗尖牙怎么办 肉卡在牙缝里怎么办 电脑做系统卡死怎么办 苹果6升级太卡怎么办