【问题标题】:Improving query access performance for unordered maps that are unchanging提高不变的无序映射的查询访问性能
【发布时间】:2019-06-05 20:07:23
【问题描述】:

我正在寻找改进无序地图查询时间访问的建议。我的代码基本上只包含两个步骤。第一步,我填充无序地图。在第一步之后,不再向地图添加条目。第二步,只查询无序地图。由于地图本质上是不变的,有什么办法可以加快查询时间? 例如,stl 是否提供任何可以调整映射中的内部分配以改善查询时间访问的功能?换句话说,有可能不止一个键被映射到无序映射中的同一个桶。如果为映射分配了更多内存,则可以减少发生此类冲突的机会。从这个意义上说,我很好奇知道无序映射将保持不变这一事实是否可以做任何事情。

【问题讨论】:

  • Here 是您了解地图访问复杂性的一个很好的参考。
  • @muaz- 感谢您的评论。我想我对这个问题的早期版本不是很清楚。请查看更新版本。是的,我知道访问的平均案例复杂性。
  • map 是一个哈希表,因此如果您使用自定义的类或结构作为键,那么是否发生冲突取决于您的哈希函数,即分配的内存与冲突无关。
  • @muaz: "...冲突取决于您的哈希函数..." - 不是这样 - 哈希函数通常返回 32 位或 64 位值,然后将其屏蔽(按位与)或进行%-模运算以将哈希值映射到特定的哈希桶;哈希桶的数量 - 用 C++ 的说法,capacity() - 是 batwing 一直在考虑的,增加容量(显然降低负载因子并且)倾向于减少冲突,因为现在相同的哈希函数将映射一些对额外的桶进行掩码或修改后的值。
  • Tony,如果哈希函数为两个不同的输入返回相同的值,那么无论哈希表中有多少个桶,它们最终都会在同一个桶中。

标签: c++11 unordered-map


【解决方案1】:

如果测量结果表明这对您很重要,那么我建议对标准库之外的其他哈希表实现进行测量,例如google's。使用 封闭式哈希 又名 开放式寻址 可能对您更有效,尤其是当您的哈希表条目小到可以直接存储在哈希表存储桶中时。

更一般地说,Marshall 建议找到一个好的散列函数。不过要小心——有时通常“坏”的哈希函数比“好”的哈希函数表现得更好,如果它与你的键的某些属性很好地配合的话。例如,如果您倾向于使用递增的数字,可能会有一些间隙,那么只返回密钥的身份(又名微不足道)哈希函数可以选择比伪随机(但可重复)的加密哈希具有更少冲突的哈希桶) 将键分散在不相关的桶中,差异只有一点点。如果您正在查找几个附近的键值,身份哈希也可以提供帮助,因为它们的存储桶可能也在附近,您将获得更好的缓存利用率。但是,您没有告诉我们有关您的键、值、条目数等的信息 - 所以剩下的就交给您了。

【讨论】:

    【解决方案2】:

    您有两个可以转动的旋钮:哈希函数和地图中的桶数。一个在编译时固定(散列函数),另一个您可以在运行时修改(有些)。

    一个好的散列函数会给你很少的冲突(具有相同散列值的不相等值)。如果您有很多冲突,那么您实际上无法做很多事情来改善您的查找时间。最坏的情况(所有输入散列到相同的值)为您提供 O(N) 查找时间。所以这就是你要集中精力的地方。

    一旦你有一个好的哈希函数,那么你就可以玩有桶数的游戏(通过rehash),这可以进一步减少冲突。

    【讨论】:

      猜你喜欢
      • 2023-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-03
      • 1970-01-01
      相关资源
      最近更新 更多