C++ C++;:预期大量未命中:映射与无序映射

C++ C++;:预期大量未命中:映射与无序映射,c++,dictionary,unordered-map,C++,Dictionary,Unordered Map,我不熟悉C++中的工具。如果这个问题听起来像垃圾,请原谅 从map.find(),复杂性是O(log(N))。这似乎暗示了实现中的树结构 从无序的\u map.find(),平均复杂度是恒定的,而最坏的情况是O(N)。这看起来像一个哈希表 我正在寻找一种可以让我: 预先分配内存,即我确切知道有多少项将进入地图 在地图中找不到大量查询时,具有良好的性能,我知道这将在我的用例中发生 unordered_-map满足(1)与unordered_-map的要求。重新刷新,但未找到的查询可能需要很长时间m

我不熟悉
C++
中的工具。如果这个问题听起来像垃圾,请原谅

map.find()
,复杂性是
O(log(N))
。这似乎暗示了实现中的树结构

无序的\u map.find()
,平均复杂度是恒定的,而最坏的情况是
O(N)
。这看起来像一个哈希表

我正在寻找一种可以让我:

  • 预先分配内存,即我确切知道有多少项将进入地图
  • 在地图中找不到大量查询时,具有良好的性能,我知道这将在我的用例中发生

  • unordered_-map
    满足(1)与
    unordered_-map的要求。重新刷新
    ,但未找到的查询可能需要很长时间
    map
    对于未找到的查询似乎有更好的性能,但没有预分配mem功能。有什么建议吗?

    拥有一个固定数量的项目往往意味着您要插入一些特定的项目,然后将它们保留在集合中,直到完成为止

    如果是这样的话,我可能会将这些项目放入
    std::vector
    并对它们进行排序。然后,如果分布是合理可预测的,则使用插值搜索,否则使用二进制搜索

    只要您不必插入/删除更多的项目并保留顺序,这通常比树快很多,即使您使用二进制搜索,因为数据是连续的


    如果你在搜索中期望有很多错误,我会考虑一个哈希表(unOrdEdj-MAP),将其设置成一个非常低的负载因子,因此绝大多数时间,你会把密钥散列,如果它不存在,那么你很可能会在一个空散列桶上着陆,这是非常好的。因此,您将得到一个迹象,表明搜索很快就失败了。您可以使用

    max\u load\u factor()

    A设置负载系数,它适用于您期望大量未命中的情况。它有点像一个哈希表,只是它使用了多个哈希,实际上并不在表中存储项,只是告诉您该项是否不是集合的一部分。如果未找到,它会很快告诉您,如果筛选器指示可能匹配,则需要使用辅助方法(如建议的方法)进行第二次查找。

    为什么哈希表在未找到的查询上性能不佳?一般来说,由于哈希值与表中的任何内容都不匹配,因此会很快检测到未找到的查询。这个查询的大小是多少?如果它很小,
    std::vector
    实际上可能比所有缓存不友好的映射都要好。@NicolBolas最坏情况
    O(N)
    表明它正在为冲突重新灰化,这意味着
    map
    如果找不到键,可能会耗尽表。@Mai:O(N)如果放入表中的每个项都有相同的哈希代码,则会发生最坏情况。它与重新灰化无关。@Mai:
    无序映射
    通常通过使用每个bucket中的链表(或相关结构)链接来(粗略地)处理冲突。因此,如果两个项目散列到同一个bucket,它只会将第二个项目追加到链表中;第一个项目的查找将需要一个散列、查找,并且它会立即被找到,第二个项目的查找需要沿着链接列表进行一次额外的检查,散列到该存储桶的缺失项目将支付与查找第二个项目相同的费用(沿着链接列表进行两次遍历,然后在结束时放弃)。