对于基本类型,使用emplace值得吗?

8

假设我有一个 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有什么好处吗?

1个回答

12

如果 emplace 操作有可能失败(键已存在),则 emplace 操作速度较慢。

原因是 emplace 操作必须分配一个节点并将 pair<Key const, Value> 构造到其中,然后从该节点中提取键并检查键是否已经存在,如果键已存在,则需要释放该节点。相比之下,insert 操作可以从要插入的值中提取键,所以如果插入操作失败,则不需要分配节点。详情请参见:performance of emplace is worse than check followed by emplace

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接