对于基本类型来说值得

Is emplace for basic types worth it?

本文关键字:值得 类型 于基本      更新时间:2023-10-16

假设我有一个map<int, int>

std::map<int, int> map;
map.emplace(1, 2);
map.insert({3, 4});

两个调用之间会有什么区别吗?

在第一次调用中,两个整数将按值复制到 emplace 函数,然后再次复制到 std::pair<int, int> 构造函数。在第二次调用中,两个整数将按值复制到std::pair<int, int>构造函数,然后作为第一对的成员再次按值复制到内部std::pair<int, int>

我理解 emplace 对于像 std::string 这样的类型的好处,它们将在第二次调用中按值复制并在第一次调用中一直移动,但是在所述情况下使用emplace有什么好处吗?

如果 emplace 有可能失败(键已经存在),Emplace 会变慢。

这是因为需要emplace分配节点并在其中构造pair<Key const, Value>,然后从该节点中提取密钥并检查密钥是否已存在,如果密钥已存在,则取消分配节点。另一方面,insert可以从要插入的传递值中提取键,因此如果插入失败,则不需要分配节点。请参阅:emplace的性能比检查差,其次是emplace。

为了解决这个问题,C++17 try_emplace(const key_type& k, Args&&... args)(等)添加一个成员函数。

在成功的情况下,这两种情况之间没有真正的区别;操作的顺序不同,但这不会以任何可预测的方式影响性能。对于emplace变体,代码大小仍将略大,因为它必须准备好在失败情况下执行更多工作。