考虑如下代码:
#include <iostream> #include <map> #include <string> #include <boost/chrono.hpp> #include <boost/timer/timer.hpp> int main() { std::map<int, std::string> a{ { 1, "one" }, { 2, "two" }, { 3, "buckle my shoe" } }; std::map<int, std::string> b{ { 3, "three" } }; //计算函数调用占用的时间 boost::timer::cpu_timer timer; for (int i=0;i<10000;++i){ { auto ite = a.find(2); auto [k,v] = *ite; b.emplace(std::make_pair(k, v)); a.erase(ite); } { auto ite = b.find(2); auto [k,v] = *ite; a.emplace(std::make_pair(k, v)); b.erase(ite); } } boost::timer::cpu_times time = timer.elapsed(); int wall_time_ = time.wall / 1000000; //纳秒转毫秒 std::cout << "elasped time=" << wall_time_; }
把元素2(key==2)在a,b两个容器之间移动。涉及到heap的内存分配和释放。当insert时,发生malloc,当erase时,发生free。
C++17开始,支持无heap动作的元素搬移:
#include <iostream> #include <map> #include <string> #include <boost/chrono.hpp> #include <boost/timer/timer.hpp> int main() { std::map<int, std::string> a{ { 1, "one" }, { 2, "two" }, { 3, "buckle my shoe" } }; std::map<int, std::string> b{ { 3, "three" } }; //计算函数调用占用的时间 boost::timer::cpu_timer timer; for (int i=0;i<10000;++i){ b.insert(a.extract(2)); auto ite = b.find(2); a.insert(b.extract(ite)); } boost::timer::cpu_times time = timer.elapsed(); int wall_time_ = time.wall / 1000000; //纳秒转毫秒 std::cout << "elasped time=" << wall_time_; }
关键在于extract函数,它返回一个node handle