1、emplace_back减少内存拷贝和移动
emplace_back能通过参数构造对象,不需要拷贝或者移动内存,相比pusk_back能更好的避免内存的拷贝和移动,使容器插入元素性能得到进一步提升。几乎所有的标准库容器都增加了类型的方法:emplace,emplace_hint,emplace_front,emplace_after和emplace_back。
基本用法:
#include <iostream> #include <vector> using namespace std; struct A { int x; double y; A(int a, double b): x(a), y(b){} }; int main() { vector<A> v; v.emplace_back(1, 2.0); cout << v.size() << endl; return 0; }
用法还是很简单的,直接通过构造函数的参数就可以构造对象,当然,要求对象有相应的构造函数,如果没有构造函数会报错。
emplace_back相对push_back更有性能优势。
#include <iostream> #include <vector> #include <map> using namespace std; struct A { int x; double y; string name; A(int a, double b, string c):x(a), y(b), name(c) { cout << "construct" << endl; } A(const A &a): x(a.x), y(a.y), name(std::move(a.name)) { cout << "move" << endl; } }; int main() { map<int, A> m; int i = 4; double d = 2.0; string s = "C++11"; cout << "--insert--" << endl; m.insert(make_pair(2, A(i, d, s))); cout << "--emplace--" << endl; m.emplace(1, A(i, d, s)); vector<A> v; cout << "--emplace_back--" << endl; v.emplace_back(i, d, s); cout << "--push_back--" << endl; v.push_back(A(i, d, s)); return 0; } //执行结果: --insert-- construct move move --emplace-- construct move --emplace_back-- construct --push_back-- construct move move
可以看出不管map还是vector,emplace系列方法在性能上面都优于之前的方法,所以尽可能的使用emplace系列方法,不过前提是类型必须有相应的构造函数。
2、unordered container无序容器
c++11提供了无序容器unordered_map/unordered_multimap和unordered_set/unordered_multiset,由于这些容器中的元素是不排序的,所以性能高于map/multimap和set/multiset。map和set是红黑树,在插入元素时会自动排序,而无序容器内部是散列表,通过hash,而不是排序来快速操作元素,使得效率更高。
对于自定义类型,无序容器的key需要提供hash_value函数,其他用法和map/set的用法是一样的。不过对于自定义的key,需要提供hash函数和比较函数。
对于基本类型来说,不需要提供hash函数和比较函数,用法和map/set一样。