std::map 插入 && 过载导致复制
std::map insert && overload causes copy
正在看这个有趣的演讲:
CppCon 2017: Matt Kulukundis “Designing a Fast, Efficient, Cache-friendly Hash Table, Step by Step”
他在大约 38:32 分钟提到
void Benchmark_Slow(int iters) {
std::unordered_map<string, int> m;
std::pair<const string, int> p = {};
while (iters--) m.insert(p)
}
比以下变体慢约 2 倍
void Benchmark_Fast(int iters) {
std::unordered_map<string, int> m;
const std::pair<const string, int> p = {};
while (iters--) m.insert(p)
}
我还在想为什么会选择&&
重载(1)。
std::pair<iterator,bool> insert( value_type&& value ); (1)
std::pair<iterator,bool> insert( const value_type& value ); (3)
其中 value_type
是 std::pair<const Key, T>
。
毕竟,我们没有移动值,所以在我的理解中,表达式 p
应该是左值而不是 x/prvalue,对吗?谁能赐教一下?
你没有接受有问题的重载:
std::pair<iterator,bool> insert(const value_type& value); // (1)
template< class P >
std::pair<iterator,bool> insert(P&& value); // (2)
P
推导为 value_type&
.
- 调用了模板重载 (overload (2) on cppreference)
- 模板重载相当于
emplace
emplace
并不比 insert
慢,而且在一般情况下更快,但是...
但是,emplace
允许一种滥用行为,即您反复尝试插入同一个密钥。基准测试正是这样做的(请注意 while
)。我想说的是,当你故意搬起石头砸自己的脚时,这只是一个显示行为的基准。在现实世界中,我不认为有人会通过 emplace
或 insert
.
来做到这一点
在 C++17 中,这已通过一种需要修改代码的方式得到修复:
try_emplace
函数 https://isocpp.org/files/papers/n4279.html
正在看这个有趣的演讲:
CppCon 2017: Matt Kulukundis “Designing a Fast, Efficient, Cache-friendly Hash Table, Step by Step”
他在大约 38:32 分钟提到
void Benchmark_Slow(int iters) {
std::unordered_map<string, int> m;
std::pair<const string, int> p = {};
while (iters--) m.insert(p)
}
比以下变体慢约 2 倍
void Benchmark_Fast(int iters) {
std::unordered_map<string, int> m;
const std::pair<const string, int> p = {};
while (iters--) m.insert(p)
}
我还在想为什么会选择&&
重载(1)。
std::pair<iterator,bool> insert( value_type&& value ); (1)
std::pair<iterator,bool> insert( const value_type& value ); (3)
其中 value_type
是 std::pair<const Key, T>
。
毕竟,我们没有移动值,所以在我的理解中,表达式 p
应该是左值而不是 x/prvalue,对吗?谁能赐教一下?
你没有接受有问题的重载:
std::pair<iterator,bool> insert(const value_type& value); // (1)
template< class P >
std::pair<iterator,bool> insert(P&& value); // (2)
P
推导为 value_type&
.
- 调用了模板重载 (overload (2) on cppreference)
- 模板重载相当于
emplace
emplace
并不比insert
慢,而且在一般情况下更快,但是...
但是,emplace
允许一种滥用行为,即您反复尝试插入同一个密钥。基准测试正是这样做的(请注意 while
)。我想说的是,当你故意搬起石头砸自己的脚时,这只是一个显示行为的基准。在现实世界中,我不认为有人会通过 emplace
或 insert
.
在 C++17 中,这已通过一种需要修改代码的方式得到修复:
try_emplace
函数 https://isocpp.org/files/papers/n4279.html