【问题标题】:std::unordered_map insert with hint带有提示的 std::unordered_map 插入
【发布时间】:2013-03-11 16:17:28
【问题描述】:

std::map 有一个 insert 方法,该方法采用“提示”迭代器,如果提示正确,该迭代器会将插入时间从 log(n) 减少到恒定时间。很明显这是如何工作的,因为容器可以确保新添加的项目具有小于提示的键并且具有大于提示之前的项目的键。否则提示是错误的,它会执行正常的插入。

std::unordered_map 也有类似的insert 带有提示功能。如果有的话,提示有什么作用?对我来说,如何使用另一个“提示”迭代器来加速哈希映射插入并不明显。

如果使用,什么是适当的“提示”。在std::map 中,通常通过在地图上调用lower_bound 来找到提示。

【问题讨论】:

  • 我认为提示重载只是为了与普通std::map 的接口兼容性,因为您必须确切知道要插入您的值的哈希值的位置才能做任何有用的事情 - 这意味着您需要考虑负载、存储桶等,基本上复制 unordered_map 在内部所做的事情。此外,正如您所指出的,无论如何,插入都是摊销的 O(1)。
  • 所以要清楚,你是说它没有做任何事情?这就是我的猜测......这只是为了兼容。

标签: c++ stl c++11


【解决方案1】:

这是一个接口兼容性问题。基本上,设计是考虑std::map的接口完成的。

换句话说,对于std::unordered_map,是否提供提示没有区别。

来自 cmets 的其他信息:

界面兼容性非常重要,因为能够在mapunordered_map 之间快速/轻松地切换提供了无痛转换的宝贵灵活性,因为性能通常是选择其中一个而不是另一个的决定因素。

【讨论】:

  • +1 是的,接口兼容性对于泛型代码非常重要(例如,容器是模板参数:template <class Map>)。能够快速/轻松地在 mapunordered_map 之间切换非常重要,因为性能通常是选择其中一个而不是另一个的决定因素。
  • @HowardHinnant:正如 OP 所指出的,通常通过调用 map::lower_bound() 来获得提示,而 unordered_map 没有此方法(因为它对于无序容器没有意义)。这不是说还没有提供接口兼容性吗?
  • @AndyT:接口兼容性有明确的限制。然而findequal_range 是其他丰富的迭代器来源,可以在这两个API 中找到。如果来回切换对您来说是一个重要目标,那么您坚持使用通用 API 子集。委员会已尽其所能使子集尽可能大,例如允许您在插入 unordered_map 时提供无用的提示。
  • @HowardHinnant:清晰度不应该比方便更重要吗?在这种情况下,便利性很小,因为只是为您提供了更多兼容的界面。我相信困惑的人试图意识到如何使用该提示参数所花费的总时间比真正需要在 map 和 unordered_map 之间切换的人赢得的时间要多。当然,这是我的主观意见。
  • @AndyT:这始终是您的选择:cplusplus.github.io/LWG/lwg-active.html#submit_issue
【解决方案2】:

提示允许无序映射实现首先进行值比较以查看提示是否有效。这避免了必须执行比比较操作更昂贵的哈希函数。

【讨论】:

  • 你能举一个例子来说明它是如何工作的吗?即,如何找到提示并使用它插入地图?
  • 我认为这里的重点是,如果提示指向正确的项目...也就是说,键已经在 unordered_map 中,那么插入会看到(通过比较提示传入的值),并且不需要计算哈希。如果键不在 unordered_map 中,我认为这种情况不会有任何改进。
  • 在我遇到的在std::map 中使用提示的典型用例中,只有在您已经知道该项目不在地图中时才使用提示调用插入,因为您首先搜索并发现它不在那里,但它会在哪里(使用lower_bound)。所以似乎在unordered_map 上使用提示,如果为真,将没有实际价值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-19
  • 2021-11-01
  • 1970-01-01
  • 2012-06-20
  • 1970-01-01
相关资源
最近更新 更多