vs2005支持 :: stdext ::的hash_map ::的std ::地图。
然而,似乎:: stdext :: hash_map的插入和删除OP比我的测试中的:: std :: map慢。 (少于10000件)
...有趣
任何人都可以发表关于他们的比较文章吗?
答案 0 :(得分:9)
通常你会看到各种操作的复杂性,这是一个很好的指南:分摊O(1)插入,O(1)查找,删除哈希映射,而不是O(log N)插入,查找,删除基于树的地图。
然而,在某些情况下,复杂性具有误导性,因为所涉及的常数术语是极端的。例如,假设您的10k项目已键入字符串。进一步假设这些字符串的长度均为100k字符。假设不同的字符串通常在字符串的开头附近不同(例如,如果它们基本上是随机的,则第一个字节中的对将有所不同,概率为255/256)。
然后要进行查找,hashmap必须散列100k字符串。这是集合大小的O(1),但可能需要相当长的时间,因为它可能是字符串长度的O(M)。平衡树必须进行log N< = 14比较,但每个只需要查看几个字节。这可能不会花很长时间。
就内存访问而言,使用64字节高速缓存行大小,hashmap加载超过1500个连续行,并执行100k字节操作,而树加载15个随机行(实际上可能是30个由于通过字符串的间接)并执行14 *(一些小数字)字节操作。你可以看到前者可能比后者慢。或者它可能更快:您的架构的FSB带宽,停顿时间和推测性读取缓存有多好?
如果查找找到匹配项,那么除此之外,两个结构都需要执行单个全长字符串比较。如果存储桶中发生冲突,则hashmap可能会执行其他失败的比较。
因此,假设失败的比较速度可以忽略不计,而成功的比较和散列运算速度很慢,那么树的速度大约是散列的1.5-2倍。如果这些假设不成立,那就不会。
当然,这是一个极端的例子,但很容易看出,在您的数据上,特定的O(log N)操作可能比特定的O(1)操作快得多。您当然需要进行测试,但如果您的测试数据不能代表现实世界,那么您的测试结果可能也不具代表性。基于复杂性的数据结构的比较是指当N接近无穷大时的极限行为。但是N并没有接近无穷大。它是10000。
答案 1 :(得分:6)
这不仅仅是关于插入和移除。您必须考虑在hash_map vs map中以不同方式分配内存,并且每次都必须计算要搜索的值的哈希值。
我认为Dr.Dobbs的这篇文章最能回答你的问题:
答案 2 :(得分:2)
这取决于您的使用情况和哈希冲突。一个是二叉树,另一个是哈希表。
理想情况下,哈希映射将具有O(1)插入和查找,以及映射O(ln n),但它假定非冲突哈希值。
答案 3 :(得分:2)
hash_map 使用hash table,它提供几乎恒定的时间O(1)操作,假设一个好的哈希函数。
地图使用BST,它提供O(lg(n))操作,对于10000个元素,这是13,这是非常可接受的
我会说留在地图上,它更安全。
答案 4 :(得分:0)
哈希表应该比二进制树(即std :: map)更快以便查找。没有人建议插入和删除更快。
答案 5 :(得分:0)
哈希映射将创建用于索引的字符串/键的哈希。尽管在证明复杂性时它被称为O(1),但hash_map对每个插入进行冲突检测,因为字符串的散列可以产生与另一个字符串的散列相同的索引。因此,散列映射具有管理这些冲突的复杂性。你知道这些碰撞是基于输入数据的。
但是,如果要对结构执行大量查找,请选择hash_map。