unordered_map和map类似,都是存储的key-value的值,可以通过key快速索引到value。不同的是unordered_map不会根据key的大小进行排序,

存储时是根据key的hash值判断元素是否相同,即unordered_map内部元素是无序的,而map中的元素是按照二叉搜索树存储,进行中序遍历会得到有序遍历。

所以使用时map的key需要定义operator<。而unordered_map需要定义hash_value函数并且重载operator==。但是很多系统内置的数据类型都自带这些,

那么如果是自定义类型,那么就需要自己重载operator<或者hash_value()了。

1.结论

结论:如果需要内部元素自动排序,使用map,不需要排序使用unordered_map

运行效率方面:unordered_map最高,而map效率较低但 提供了稳定效率和有序的序列。

占用内存方面:map内存占用略低,unordered_map内存占用略高,而且是线性成比例的。

需要无序容器,快速查找删除,不担心略高的内存时用unordered_map;有序容器稳定查找删除效率,内存很在意时候用map。

2.原理

map的内部实现是二叉平衡树(红黑树);hash_map内部是一个hash_table一般是由一个大vector,vector元素节点可挂接链表来解决冲突,来实现.

hash_map其插入过程是:
  1. 得到key
  2. 通过hash函数得到hash值
  3. 得到桶号(一般都为hash值对桶数求模)
  4. 存放key和value在桶内。
 
其取值过程是:
  1. 得到key
  2. 通过hash函数得到hash值
  3. 得到桶号(一般都为hash值对桶数求模)
  4. 比较桶的内部元素是否与key相等,若都不相等,则没有找到。
  5. 取出相等的记录的value。
 
hash_map中直接地址用hash函数生成,解决冲突,用比较函数解决。

3.性能特点

非频繁的查询用map比较稳定;频繁的查询用hash_map效率会高一些,c++11中的unordered_map查询效率会更高一些但是内存占用比hash_map稍微大点。unordered_map 就是 boost 里面的 hash_map 实现。

其实,stl::map对于与java中的TreeMap,而boost::unordered_map对应于java中的HashMap。
python中的map就是hashmap实现的,所以查询效率会比C++的map查询快。(java,python官方版的虚拟机都是用C语言实现的,所以内部的思想和方法都是通用的。)

若考虑有序,查询速度稳定,容器元素量少于1000,非频繁查询那么考虑使用map。
若非常高频查询(100个元素以上,unordered_map都会比map快),内部元素可非有序,数据大超过1k甚至几十万上百万时候就要考虑使用unordered_map(元素上千万上亿时4GB的内存就要担心内存不足了,需要数据库存储过程挪动到磁盘中)。
hash_map相比unordered_map就是千万级别以上内存占用少15MB,上亿时候内存占用少300MB,百万以下都是unordered_map占用内存少,
且unordered_map插入删除相比hash_map都快一倍,查找效率相比hash_map差不多,或者只快了一点约1/50到1/100。
综合非有序或者要求稳定用map,都应该使用unordered_map,set类型也是类似的。
unordered_map 查找效率快五倍,插入更快,节省一定内存。如果没有必要排序的话,尽量使用 hash_map(unordered_map 就是 boost 里面的 hash_map 实现)。

4.使用案例

map:

 #include<string>
#include<iostream>
#include<map> using namespace std; struct person
{
string name;
int age; person(string name, int age)
{
this->name = name;
this->age = age;
} bool operator < (const person& p) const
{
return this->age < p.age;
}
}; map<person,int> m;
int main()
{
person p1("Tom1",);
person p2("Tom2",);
person p3("Tom3",);
person p4("Tom4",);
person p5("Tom5",);
m.insert(make_pair(p3, ));
m.insert(make_pair(p4, ));
m.insert(make_pair(p5, ));
m.insert(make_pair(p1, ));
m.insert(make_pair(p2, )); for(map<person, int>::iterator iter = m.begin(); iter != m.end(); iter++)
{
cout<<iter->first.name<<"\t"<<iter->first.age<<endl;
} return ;
}

输出为:(根据age进行了排序的结果)

Tom1    20
Tom3    22
Tom4    23
Tom5    24
因为Tom2和Tom3的age相同,由我们定义的operator<只是比较的age,所以Tom3覆盖了Tom2,结果中没有Tom2。

如果运算符<的重载是如下

 bool operator < (const person &p)const{
return this->name < p.name;
}

输出结果: 按照 那么进行的排序,如果有那么相同则原来的那么会被覆盖

Tom1    20

Tom2    22

Tom3    22

Tom4    23

Tom5    24

参考:http://www.cnblogs.com/NeilZhang/p/5724996.html

http://blog.csdn.net/blues1021/article/details/45054159

unordered_map 与 map 的对比(转)的更多相关文章

  1. C++11 新特性: unordered_map 与 map 的对比

    unordered_map和map类似,都是存储的key-value的值,可以通过key快速索引到value.不同的是unordered_map不会根据key的大小进行排序, 存储时是根据key的ha ...

  2. (转)unordered_map与map的对比(C++11新特性)

    unordered_map和map类似,都是存储的key-value的值,可以通过key快速索引到value.不同的是unordered_map不会根据key的大小进行排序, 存储时是根据key的ha ...

  3. hash_map vs unordered_map vs map vs unordered_set

    hash_map vs unordered_map 这两个的内部结构都是采用哈希表来实现.unordered_map在C++11的时候被引入标准库了,而hash_map没有,所以建议还是使用unord ...

  4. 两个Map的对比,三种方法,将对比结果写入文件。

    三种方法的思维都是遍历一个map的Key,然后2个Map分别取这2个Key值所得到的Value. #第一种用entry private void compareMap(Map<String, S ...

  5. Collection与Map的对比

    Map:HashMap.HashTable  如何在它们之间选择  一.Array , Arrays  Java所有“存储及随机访问一连串对象”的做法,array是最有效率的一种.  1.  效率高, ...

  6. java Map集合对比分析

    1.Map:Map是所有map集合的顶级父接口,用于key/value形式的键值对,其中每一个key都映射到一个值,key不能重复. 2.TreeMap:该map将存储的键值对进行默认排序,并且还能够 ...

  7. 详细介绍C++STL:unordered_map

    不得不提一下,hash_map未加入在C++11标准中. 在VC中编译: #include <hash_map> using namespace stdext; hash_map<i ...

  8. map 与 unordered_map

    两者效率对比: #include <iostream> #include <string> #include <map> #include <unordere ...

  9. map,hash_map和unordered_map 实现比较

    map介绍 Map是STL[1]的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性,它完成有可能在我们处 ...

随机推荐

  1. Demystifying iOS Application Crash Logs

    http://www.raywenderlich.com/23704/demystifying-ios-application-crash-logs This is a blog post by So ...

  2. usb驱动---linux ACM驱动详解ACA【转】

    转自:http://blog.chinaunix.net/uid-9185047-id-3404684.html DTE提供或接收数据,连接到网络中的用户端机器,主要是计算机和终端设备.与此相对地,在 ...

  3. 我只能说,Spring Data REST真的很燥辣

    我自己写REST,到一半了,突然想试一下Spring Data REST,还真不是乱说, 燥辣得很,短时间全生成,快赶上DJANGO的速度了.怕了我. 参考文档: Spring Data REST入门 ...

  4. js-获取用户移动端网络类型:wifi、4g、3g、2g...

    今天工作时间很宽裕, 忽然想起,自己做过的所有页面中,有些页面经常会面临用户在网络状态很差的时候打开页面,页面是挂了的状态,感觉很LOW~. 所以我决定在今后的页面中我需要先判断用户的网络状态, 若是 ...

  5. viewflipper的高度设置

    由于ViewFlipper的一个子view是这个ImageView,ViewFilpper在切换时,高度总是为子View中高度最大的值作为其高度值. 后经搜索,发现需要设置android:measur ...

  6. Xcode_9_beta.xip 更新下载

    Xcode_9_beta.xip 更新下载 Xcode_9_beta.xip 链接: pan.baidu.com/s/1dFJ33tJ 密码: 89mv

  7. luogu P1195 口袋的天空

    题目背景 小杉坐在教室里,透过口袋一样的窗户看口袋一样的天空. 有很多云飘在那里,看起来很漂亮,小杉想摘下那样美的几朵云,做成棉花糖. 题目描述 给你云朵的个数N,再给你M个关系,表示哪些云朵可以连在 ...

  8. http 头信息详解(转)

    HTTP(HyperTextTransferProtocol)是超文本传输协议的缩写,它用于传送WWW方式的数据,关于HTTP协议的详细内容请参考RFC2616.HTTP协议采用了请求/响应模型.客户 ...

  9. 1· linux命令:查看依赖的共享库 - ldd命令

    今天使用qt链接mysql的时候,发现提示driver not load 而出现此错误一般是没有mysql驱动的原因,但是qt5.4已经提供了mysql驱动的 查看plugins/sqldrivers ...

  10. sql索引从入门到精通(十亿行数据测试报告)

    原文:sql索引从入门到精通(十亿行数据测试报告) 导读部分 --------------------------------------------------------------------- ...