STL中Map 与Hash Map

来源:互联网 发布:免费相亲软件 编辑:程序博客网 时间:2024/06/04 19:45


Summary of the difference

1. STL map is an associative array where keys are stored in sorted order using balanced trees. While hash_map is a hashed associated container, where keys are not stored in an ordered way. Key, value pair is stored using a hashed function.
2. Insertion and lookup takes Ologn time in map, Also performance would degrade as the key size increases. Mainly balance operations on large key ranges would kill performance. while lookup is very efficient O(1) in hash_map.
3. Map is useful where you want to store keys in sorted order, hash_map is used where keys order is not important and lookup is very efficient.
4. One more difference is map has the important property that inserting a new element into a map does not invalidate iterators that point to existing elements. Erasing an element from a map also does not invalidate any iterators.
Performance would mostly be o(lgn) due to the implementation of a balanced tree.
For Map custom objects you would need at the minimum the following operators to store data in a map "<" ">" "==" and of course the other stuff for deep copy.

效率

查找效率

map提供一个很常用的功能,那就是提供key-value的存储和查找功能。例如,我要记录一个人名和相应的存储,而且随时增加,要快速查找和修改。这些信息如果保存下来并不复杂,但是找起来比较麻烦。例如我要找"张三丰"的信息,最傻的方法就是取得所有的记录,然后按照名字一个一个比较。如果要速度快,就需要把这些记录按照字母顺序排列,然后按照二分法查找。但是增加记录的时候同时需要保持记录有序,因此需要插入排序。考虑到效率,这就需要用到二叉树。讲下去会没完没了,如果你使用STL 的map容器,你可以非常方便的实现这个功能,而不用关心其细节。关于map的数据结构细节,感兴趣的朋友可以参看学习STL map, STL set之数据结构基础。


与使用list这样的线性表容器相比,一可以简化查找的算法,二可以使任意的关键字做索引,并与目标对象配对,优化查找算法。
在C++的STL中map是使用树来做查找算法,这种算法差不多相当与list线性容器的折半查找的效率一样,都是 O(log2N),而list就没有map这样易定制和操作了。

相比map,hash_map使用hash表来排列配对,hash表是使用关键字来计算表位置。当这个表的大小合适,并且计算算法合适的情况下,hash表的算法复杂度为O(1)的,但是这是理想的情况下的,如果hash表的关键字计算与表位置存在冲突,那么最坏的复杂度为O(n)。

树查找,在总查找效率上比不上hash表,但是它很稳定,它的算法复杂度不会出现波动。在一次查找中,你可以断定它最坏的情况下其复杂度不会超过 O(log2N)。而hash表就不一样,是O(1),还是O(N),或者在其之间,你并不能把握。

map和hash_map具体的性能测试

大家都知道在C++的STL中map是使用树来做查找算法,而hash_map使用hash表来排列配对,是使用关键字来计算表位置。那使用起来他们的差别主要是什么呢?对于性能差别是什么,适合什么情况下应用呢?于是我对它们进行了一些测试,并记录了测试数据供大家分享。
    测试的内容主要是map和hash_map的添加、删除、查找和遍历操作,首先进行了几组测试,分别是10万次、30万次,时间单位均为毫秒,具体的性能对照如下:
 hash_map(10万) map(10万) hash_map(20万) map(20万) hash_map(30万) map(30万)
添加 93   47  156   94  203   172
遍历 16   15  16   16  16   15
查找 0   0  32   31  31   32
删除 8422   32  33765   63  76016   78
   通过上面的数据比较,我们很容易发现hash_map的添加和删除操作比map要慢,尤其是删除操作hash_map比map可能慢1000倍;从而得到结论是删除和插入操作较多的情况下,map比hash_map的性能更好,添加和删除的数据量越大越明显。但我们使用map、hash_map一般都用于查找和遍历较多,而且上述测试数据也不能反映出这两方面的性能差距,于是继续对查找和遍历进行了性能测试,得到具体数据如下,时间单位仍为毫秒:
 hash_map(100万) map(100万) hash_map(200万) map(200万) hash_map(300万) map(300万)
遍历 94   31  203   32  297   47
查找 94   234  188   531  281   875
   通过上面的测试数据可以得出结论是map的遍历性能高于hash_map,而查找性能则相反,hash_map比map要好,数据量越大查找次数越多,表现就越好。
   两大组测试完毕,整体结论也可以得出:一般应用情况下,我们保存的数据不超过100万份,查找的频繁程度不高情况下使用map性能比较好;而保存的数据较多时(超过100万),查找频繁时使用hash_map的性能就高于map了。

测试环境具体如下:
操作系统:Windows XP Professional (5.1, Build 2600) Service Pack 3(2600.xpsp_sp3_gdr.080814-1236)
编译环境:Microsoft Visual C++ 2005
 55603-007-4000003-41525
处理器:Intel(R) Core(TM)2 DuoCPU    P8600  @ 2.40GHz (2 CPUs)
内存:2044MB RAM,
    另外,整个测试仅使用物理内存,而没有虚拟内存,使用Release版本直接在控制台中运行,而没有在IDE中运行,避免影响性能;且对于较短时间计时,少于20毫秒以下可能不准确。


其他的区别介绍在这个链接,非常清晰。

http://stlchina.huhoo.net/twiki/bin/view.pl/Main/STLDetailHashMap#4.1%20hash_map%E5%92%8Cmap%E7%9A%84%E5%8C%BA%E5%88%AB%E5%9C%A8%EF%BF%BD


原创粉丝点击