转载地址:https://blog.csdn.net/whizchen/article/details/9286557

原理介绍

map介绍

map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。这里说下map内部数据的组织,map内部自建一颗红黑树(一种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的,后边我们会见识到有序的好处。

hash_map介绍

hash_map基于hash table(哈希表)。 哈希表最大的优点,就是把数据的存储和查找消耗的时间大大降低,几乎可以看成是常数时间;而代价仅仅是消耗比较多的内存。然而在当前可利用内存越来越多的情况下,用空间换时间的做法是值得的。另外,编码比较容易也是它的特点之一。

其基本原理是:使用一个下标范围比较大的数组来存储元素。可以设计一个函数(哈希函数,也叫做散列函数),使得每个元素的关键字都与一个函数值(即数组下标,hash值)相对应,于是用这个数组单元来存储这个元素;也可以简单的理解为,按照关键字为每一个元素“分类”,然后将这个元素存储在相应“类”所对应的地方,称为桶。

但是,不能够保证每个元素的关键字与函数值是一一对应的,因此极有可能出现对于不同的元素,却计算出了相同的函数值,这样就产生了“冲突”,换句话说,就是把不同的元素分在了相同的“类”之中。 总的来说,“直接定址”与“解决冲突”是哈希表的两大特点。

hash_map,首先分配一大片内存,形成许多桶。是利用hash函数,对key进行映射到不同区域(桶)进行保存。其插入过程是:

1.得到key
2.通过hash函数得到hash值
3.得到桶号(一般都为hash值对桶数求模)
4.存放key和value在桶内。
其取值过程是:
1.得到key
2.通过hash函数得到hash值
3.得到桶号(一般都为hash值对桶数求模)
4.比较桶的内部元素是否与key相等,若都不相等,则没有找到。
5.取出相等的记录的value。
hash_map中直接地址用hash函数生成,解决冲突,用比较函数解决。这里可以看出,如果每个桶内部只有一个元素,那么查找的时候只有一次比较。当许多桶内没有值时,许多查询就会更快了(指查不到的时候).

由此可见,要实现哈希表, 和用户相关的是:hash函数和比较函数。这两个参数刚好是我们在使用hash_map时需要指定的参数。

unordered_map介绍

Unordered maps are associative containers that store elements formed by the combination of a_key value_and a_mapped value_, and which allows for fast retrieval of individual elements based on their keys.

In anunordered_map, the_key value_is generally used to uniquely identify the element, while the_mapped value_is an object with the content associated to this_key_. Types of_key_and_mapped_value may differ.

Internally, the elements in theunordered_mapare not sorted in any particular order with respect to either their_key_or_mapped_values, but organized into_buckets_depending on their hash values to allow for fast access to individual elements directly by their_key values_(with a constant average time complexity on average).

unordered_mapcontainers are faster thanmapcontainers to access individual elements by their_key_, although they are generally less efficient for range iteration through a subset of their elements.

Unordered maps implement the direct access operator (operator[]) which allows for direct access of the_mapped value_using its_key value_as argument.

unordered_map与map的区别

boost::unordered_map, 它与 stl::map的区别就是,stl::map是按照operator<比较判断元素是否相同,以及比较元素的大小,然后选择合适的位置插入到树中。所以,如果对map进行遍历(中序遍历)的话,输出的结果是有序的。顺序就是按照operator< 定义的大小排序。
而boost::unordered_map是计算元素的Hash值,根据Hash值判断元素是否相同。所以,对unordered_map进行遍历,结果是无序的。
用法的区别就是,stl::map 的key需要定义operator< 。 而boost::unordered_map需要定义hash_value函数并且重载operator==。对于内置类型,如string,这些都不用操心。对于自定义的类型做key,就需要自己重载operator< 或者hash_value()了。
最后,说,当不需要结果排好序时,最好用unordered_map。
其实,stl::map对于与java中的TreeMap,而boost::unordered_map对应于java中的HashMap。

测试代码

/**
比较map、hash_map和unordered_map的执行效率以及内存占用情况
**/#include <sys/types.h>
#include <unistd.h>
#include <sys/time.h>
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <ext/hash_map>
#include <tr1/unordered_map>using namespace std;using namespace __gnu_cxx;using namespace std::tr1;#define N 100000000  //分别测试N=100,000、N=1,000,000、N=10,000,000以及N=100,000,000//分别定义MapKey=map<int,int>、hash_map<int,int>、unordered_map<int,int>
//typedef map<int,int> MapKey;          //采用map
//typedef hash_map<int,int> MapKey;     //采用hash_map
typedef unordered_map<int,int> MapKey;  //采用unordered_mapint GetPidMem(pid_t pid,string& memsize)
{char filename[1024];snprintf(filename,sizeof(filename),"/proc/%d/status",pid);ifstream fin;fin.open(filename,ios::in);if (! fin.is_open()){cout<<"open "<<filename<<" error!"<<endl;return (-1);}char buf[1024];char size[100];char unit[100];while(fin.getline(buf,sizeof(buf)-1)){if (0 != strncmp(buf,"VmRSS:",6))continue;sscanf(buf+6,"%s%s",size,unit);memsize = string(size)+string(unit);}fin.close();return 0;
}int main(int argc, char *argv[])
{struct timeval begin;struct timeval end;MapKey MyMap;gettimeofday(&begin,NULL);for(int i=0;i<N;++i)MyMap.insert(make_pair(i,i));gettimeofday(&end,NULL);cout<<"insert N="<<N<<",cost="<<end.tv_sec-begin.tv_sec + float(end.tv_usec-begin.tv_usec)/1000000<<" sec"<<endl;for(int i=0;i<N;++i)MyMap.find(i);gettimeofday(&end,NULL);cout<<"insert and getall N="<<N<<",cost="<<end.tv_sec-begin.tv_sec + float(end.tv_usec-begin.tv_usec)/1000000<<" sec"<<endl;string memsize;GetPidMem(getpid(),memsize);cout<<memsize<<endl;return 0;
}

运行结果

记录数N=100000时,结果如下:

Map类型

插入耗时,单位秒

插入加遍历耗时,单位秒

内存占用情况

map

0.110705

0.171859

5,780kB

hash_map

0.079074

0.091751

5,760kB

unordered_map

0.041311

0.050298

5,216kB

记录数N=1000000时,结果如下:

Map类型

插入耗时,单位秒

插入加遍历耗时,单位秒

内存占用情况

map

1.22678

1.95435

47,960kB

hash_map

0.684772

0.814646

44,632kB

unordered_map

0.311155

0.386898

40,604kB

记录数N=10000000时,结果如下:

Map类型

插入耗时,单位秒

插入加遍历耗时,单位秒

内存占用情况

map

14.9517

23.9928

469,844kB

hash_map

5.93318

7.18117

411,904kB

unordered_map

3.64201

4.43355

453,920kB

记录数N=100000000时,结果如下:

Map类型

插入耗时,单位秒

插入加遍历耗时,单位秒

内存占用情况

map

167.941

251.591

4,688,692kB

hash_map

46.3518

57.6972

3,912,632kB

unordered_map

28.359

35.122

4,3012,56kB

结果分析

运行效率方面:unordered_map最高,hash_map其次,而map效率最低

占用内存方面:hash_map内存占用最低,unordered_map其次,而map占用最高

map,hash_map和unordered_map效率比较相关推荐

  1. 【数据结构笔记】B树和B+树的实现,哈希查找,STL中的hash_map和unordered_map容器用法

    B和B+树 哈希查找 用开放定址法解决哈希冲突的哈希查找算法 链地址法: 利用哈希表查找一个字符串中第一个只出现一次的字符 hash_map和unordered_map 设计算法删除重复的元素 设计算 ...

  2. STL map与Boost unordered_map - 有何不可的日志 - 网易博客

    STL map与Boost unordered_map - 有何不可的日志 - 网易博客 STL map与Boost unordered_map 2012-03-30 16:06:26|  分类: c ...

  3. linux进程map,linux下unordered_map和map在小数据下性能差异

    说起性能,没有测试,还是没有发言权: #include #include #include #include #include #include #include #include #include ...

  4. Map循环/迭代/遍历效率、性能问题。

    项目开发完毕,为了找点事打发一下时间,于是用findBugs插件对当前完工的项目进行扫描,发现了很多问题.其中有个关于性能的问题,在这里记录一下. 提示信息为:Inefficient use of k ...

  5. std::map与std::unordered_map

    map和unordered_map都是键值对的储存结构.但二者存在不同,运用场景也不同. std::map map支持键值的自动排序,底层机制是红黑树,红黑树的查询和维护时间复杂度均为 O ( l o ...

  6. c++ set unordered_set区别

    c++ std中set与unordered_set区别和map与unordered_map区别类似: set基于红黑树实现,红黑树具有自动排序的功能,因此map内部所有的数据,在任何时候,都是有序的. ...

  7. map unordered_map hash_map的查找性能测试

    结论如下: Release模式下: 1. 容量为10的时候,查找效率:map > unordered_map > hash_map 2. 容量为100的时候,查找效率:map = unor ...

  8. C++ std map unordered_map hash_map 的查找性能测试代码及结果

    C++ std map unordered_map hash_map 的查找性能测试代码.过程及结果 测试环境 测试结果 测试代码 测试过程记录 测试版本 RLEASE x64 测试版本 Debug ...

  9. 关于STL中的map和hash_map

    在网上看到有关STL中hash_map的文章,以及一些其他关于STL map和hash_map的资料,总结笔记如下:     1.STL的map底层是用红黑树实现的,查找时间复杂度是log(n):   ...

最新文章

  1. Redis混合存储产品与架构介绍
  2. word 另存为xml后,读取xml的图片数据
  3. 搞 java7 年,我有点想法想和大家聊聊
  4. Oracle 11g 新特性 -- Invisible Indexes(不可见的索引) 说明
  5. 图谱特征与卷积神经网络的名优大米无损鉴别
  6. 《快速开发》通过Maven创建WebService项目Hello World!
  7. 【语音识别】基于matlab动态时间规整(DTW)孤立字语音识别【含Matlab源码 573期】
  8. python处理xps文件_如何在Windows 10系统中处理XPS文件
  9. 请教一个能在WinPE环境下获取系统相关信息的代码
  10. std::numeric_limits的使用
  11. ocr移动端名片识别
  12. opencv学习笔记之像素处理
  13. GitHub完整使用教程
  14. 毛玻璃效果在Android的实现
  15. Android字体加粗的几种样式
  16. spark python_Python、流、SQL 有更新!耗时两年,Spark 3.0 重磅发布!
  17. vue设置右边距_那些PPT高手,都是怎样设置软件的
  18. 对HackTheBox里面的Netmon进行攻破
  19. c++编写手机小游戏代码_经典小游戏大集合(C++ 源码)
  20. 90后人均负债12万,这届年轻人大多都在靠借钱过日子!

热门文章

  1. 模型的预训练/迁移学习
  2. php connection reset,connection reset by peer问题总结及解决方案
  3. hexo搭建简易的博客网站
  4. 悬镜安全 | 第八期 全球一周安全情报(9.10-9.16)
  5. k8s集群环境namespace共享和隔离
  6. 倒车与移库-汽车倒车移库技巧
  7. 墨天轮高分技术文档分享——Oracle升级迁移篇(共96个)
  8. LCD驱动分析【转】
  9. 乱入 ps。photoshop cs6菜单界面太小怎么调大
  10. 【Python ----代码规范 】