为什么C++ map容器emplace()、emplace_hint()的执行效率比insert()高?
上一节在学习 C++STL map 容器的 emplace() 和 emplace_hint() 的基本用法时,还遗留了一个问题,即为什么 emplace() 和 emplace_hint() 的执行效率会比 insert() 高?
原因很简单,它们向 map 容器插入键值对时,底层的实现方式不同:
也就是说,向 map 容器中插入键值对时,emplace() 和 emplace_hint() 方法都省略了移动键值对的过程,因此执行效率更高。下面程序提供了有利的证明:
从输出结果可以看出,在使用 insert() 方法向 map 容器插入键值对时,整个插入过程调用了 1 次 tempDemo 类的构造函数,同时还调用了 2 次移动构造函数。实际上,程序第 28 行代码底层的执行过程,可以分解为以下 3 步:
原因很简单,它们向 map 容器插入键值对时,底层的实现方式不同:
- 使用 insert() 向 map 容器中插入键值对的过程是,先创建该键值对,然后再将该键值对复制或者移动到 map 容器中的指定位置;
- 使用 emplace() 或 emplace_hint() 插入键值对的过程是,直接在 map 容器中的指定位置构造该键值对。
也就是说,向 map 容器中插入键值对时,emplace() 和 emplace_hint() 方法都省略了移动键值对的过程,因此执行效率更高。下面程序提供了有利的证明:
#include <iostream> #include <map> //map #include <string> //string using namespace std; class testDemo { public: testDemo(int num) :num(num) { std::cout << "调用构造函数" << endl; } testDemo(const testDemo& other) :num(other.num) { std::cout << "调用拷贝构造函数" << endl; } testDemo(testDemo&& other) :num(other.num) { std::cout << "调用移动构造函数" << endl; } private: int num; }; int main() { //创建空 map 容器 std::map<std::string, testDemo>mymap; cout << "insert():" << endl; mymap.insert({ "https://www.xinbaoku.com/stl/", testDemo(1) }); cout << "emplace():" << endl; mymap.emplace( "https://www.xinbaoku.com/stl/:", 1); cout << "emplace_hint():" << endl; mymap.emplace_hint(mymap.begin(), "https://www.xinbaoku.com/stl/", 1); return 0; }程序输出结果为:
insert():
调用构造函数
调用移动构造函数
调用移动构造函数
emplace():
调用构造函数
emplace_hint():
调用构造函数
从输出结果可以看出,在使用 insert() 方法向 map 容器插入键值对时,整个插入过程调用了 1 次 tempDemo 类的构造函数,同时还调用了 2 次移动构造函数。实际上,程序第 28 行代码底层的执行过程,可以分解为以下 3 步:
//构造类对象 testDemo val = testDemo(1); //调用 1 次构造函数 //构造键值对 auto pai = make_pair("https://www.xinbaoku.com/stl/", val); //调用 1 次移动构造函数 //完成插入操作 mymap.insert(pai); //调用 1 次移动构造函数而完成同样的插入操作,emplace() 和 emplace_hint() 方法都只调用了 1 次构造函数,这足以证明,这 2 个方法是在 map 容器内部直接构造的键值对。
因此,在实现向 map 容器中插入键值对时,应优先考虑使用 emplace() 或者 emplace_hint()。
所有教程
- C语言入门
- C语言编译器
- C语言项目案例
- 数据结构
- C++
- STL
- C++11
- socket
- GCC
- GDB
- Makefile
- OpenCV
- Qt教程
- Unity 3D
- UE4
- 游戏引擎
- Python
- Python并发编程
- TensorFlow
- Django
- NumPy
- Linux
- Shell
- Java教程
- 设计模式
- Java Swing
- Servlet
- JSP教程
- Struts2
- Maven
- Spring
- Spring MVC
- Spring Boot
- Spring Cloud
- Hibernate
- Mybatis
- MySQL教程
- MySQL函数
- NoSQL
- Redis
- MongoDB
- HBase
- Go语言
- C#
- MATLAB
- JavaScript
- Bootstrap
- HTML
- CSS教程
- PHP
- 汇编语言
- TCP/IP
- vi命令
- Android教程
- 区块链
- Docker
- 大数据
- 云计算