当 inserting/emplacing 新元素进入 unordered_map/unordered_set 时提示

Hint when inserting/emplacing new element into unordered_map/unordered_set

如果我在 std::unordered_map 中插入一个新元素(键不存在),我可以使用 emplace_hint 提高性能吗? 提示应该有什么价值?

我经常知道键值(整数类型)比映射中的所有键都大。那我应该使用 cend 作为提示吗?

emplace_hint 在使用无序容器时并不是真正需要的。与 std::map 不同,您有保证的顺序并使用 end 作为提示会给您恒定的位置,无序版本已经具有恒定的位置。

如果我们查看 Table 70 — Unordered associative container requirements (in addition to container) 我们有

Expects: value_­type is Cpp17EmplaceConstructible into X from args.

Effects: Equivalent to a.emplace( std::forward<​Args>(​args)...). Return value is an iterator pointing to the element with the key equivalent to the newly inserted element. The const_­iterator p is a hint pointing to where the search should start. Implementations are permitted to ignore the hint.

而且您可以看到,您甚至不能保证提供提示会起作用。

The const_­iterator p is a hint pointing to where the search should start

让我相信迭代器需要位于要放置元素的桶的开头,因此 end/cend 不会是您想要使用的。

我做了一些测试,据我所见,std::unordered_map 似乎完全忽略了提示。我找不到任何似乎可以提供任何优势的价值传递给它。

该标准明确给出了无序集合的实现以忽略传递给 emplace_hint 的提示,我认为大多数(如果不是全部)通常会这样做。该规范并没有真正说明您是否应该将迭代器传递给被插入的值(如果有的话)或过去的值(就像您对有序关联集合所做的那样)。鉴于它是 hash-based,near 的迭代器正确的插入点可能是无用的。因此,为了让它有任何好处,它可能需要成为实际插入点的迭代器(例如,如果您尝试插入重复项,则与您插入的键具有相同键的迭代器)。

总结

我怀疑您可以传递任何具有显着优势的值(并且在测试中,我还没有找到可以提供的值)。