一些hashtable / unordered_map问题

时间:2013-10-21 16:18:46

标签: c++ hashmap hashtable unordered-map low-latency

我正在开发一种低延迟的应用程序,它需要始终保持高效率。

我需要根据字符串查找一些索引,所以我使用的是c ++ unordered_map。 约束: - 仅插入和查找,无删除 -key是字符串,值是int - 期望将不超过100万个条目添加到unordered_map

  • 我将unordered_map保留设置为100万,这是好还是我应该保留比预期条目多一些的订单以避免重复? 我可以将它设置为100万或者我应该设置为接近1百万或2个功率的大素数。

  • 我在c ++ std lib中使用默认字符串哈希函数,恰好是murmur2。 我的键在25到50个字符之间,所有都是包含数字,大写英文字母和_字符的唯一键。这个哈希函数是否足以均匀地分配密钥,或者我是否需要为unordered_map提供更好的哈希函数?

  • 当我调用reserve或者保留时,unordered_map是否为100万个键,值对以及大小为100万的数组分配空间,只创建该大小的数组,并动态分配键值对插入?

  • 插入时堆上的键值对的动态分配会有多大的阻力?特别是因为这是一个包含许多条目的大哈希表。

  • 出于性能原因,最好是实现我自己的哈希表,在堆栈或init期间为内存预先分配1百万个条目,或者unordered_map的上述优化是否足够接近?

  • 有没有办法预先为unorderd_map中的预期条目数分配内存,以避免插入时的动态分配?

1 个答案:

答案 0 :(得分:1)

让我们尝试用代码回答其中的一些问题。我没有粘贴整个东西,因为它有点长。请找到所有代码here。我在这里粘贴部分输出:

Map without reserve

        size: 0
bucket_count: 23
 load_factor: 0

Allocation count: 0

... 
about 15 reallocations deleted 
...

Allocation count: 1000015

        size: 1000000
bucket_count: 1236397
 load_factor: 0.808802

0: 550454
1: 445645
2: 180174
3: 48593
4: 9708
5: 1568
6: 231
7: 22
8: 2

Map with reserve

        size: 0
bucket_count: 23
 load_factor: 0

Allocation count: 1

        size: 0
bucket_count: 2144977
 load_factor: 0

Allocation count: 1000000

        size: 1000000
bucket_count: 2144977
 load_factor: 0.466205

0: 1346008
1: 626748
2: 146625
3: 22663
4: 2669
5: 248
6: 15
7: 1
  • 如您所见,当您为1m元素保留空间时,只会发生一次分配。我想这就是桶。
  • 保留的桶数远远高于1米。
  • 分配数与插入的元素数完全相同。
  • 您可以看到每种情况的哈希分布:存在大量冲突。有时每桶最多8个元素,即使有50万个桶是空的。
  • 在没有初始reserve的情况下,大约有15次重新分配,但结果地图的桶数较少。
  • 足够大的reserve根本没有重新分配。
  • 当然,您可以滚动自己的哈希表。例如,您可以为所有键保留一个连续的空间块,因为它们每个不超过50个字节,并且值为块。但我相信这将是一项相当大的工作,可能没有好处。在开始重新实现可能不必要的内容之前,配置并记录内存分配。