push_back, emplace_back, emplace都是往容器中添加一个元素,后两者是c++11新加的,它们三者的区别在于,push_back添加元素,需要先调用被添加元素的构造函数,再调用移动构造函数。而emplace_back和emplace_back只需要调用一次构造函数, 举个例子。
vector<int> vec;
v.push_back(1);
v.emplace_back(2);
v.emplace(v.end(),3);
1作为实参传入push_back时,需要先构造一个整数对象1,然后调用移动构造函数将对象1存入vec中,调用了两次构造函数;而emplce和emplace_back直接将构造的对象存入vec中。
#include
#include
#include
using namespace std;
const int N = 1000;
class A {
private:
int age;
string name;
public:
A(int age, string name):age(age), name(name){
}
};
int main() {
vector<A> vec;
clock_t start, end;
start = clock();
A a(1,"xx");
for (int i = 0; i < N; i++) {
vec.push_back({1,"xx"});
}
end = clock();
cout<<"push_back, time1 = "<<double(end-start)/CLOCKS_PER_SEC<<"s"<<endl;
start = clock();
for (int i = 0; i < N; i++) {
vec.emplace_back(1,"xx");
}
end = clock();
cout<<"emplace_back, time2 = "<<double(end-start)/CLOCKS_PER_SEC<<"s"<<endl;
start = clock();
for (int i = 0; i < N; i++) {
vec.emplace(vec.end(), 3,"xz");
}
end = clock();
cout<<"emplace time3 = "<<double(end-start)/CLOCKS_PER_SEC<<"s"<<endl;
return 0;
}
以下是测试结果,测试环境为win10,i5 cpu,
N | push_back | emplace_back | emplace |
---|---|---|---|
1k | 0s | 0s | 0s |
1w | 0.015s | 0s | 0s |
10w | 0.046s | 0.016s | 0.047s |
100w | 0.283s | 0.168s | 0.266s |
1000w | 3.137s | 2.283s | 1.641s |
结论:
在数据量较少(1w)以内,三者几乎无区别,耗时接近于0s; 数据量在1w至100w时, emplace_back性能最优,push_back和emplace相当;数据量达到1000w时,emplace比emplace_back和push_back都要快。
对于大多数时候,我们只需要知道怎么去调用,怎么传入参数,但是,涉及到性能方面或者调优时,就需要更深入了解其中的实现原理。
C++ STL vector插入元素(insert()和emplace())详解
C++ STL vector添加元素(push_back()和emplace_back())详解
emplace_back/emplace 与 push_back/insert 效率的详细比较