C++ emplace_back × push_back
Date: 2023-01-24Last modified: 2024-02-26
Table of contents
⚡
You should use push_back when:
-
You already have a copy of the element that you want to insert into the vector.
-
The object you want to insert is cheap to copy. * The object has a non-explicit copy constructor
⚡
You should use emplace_back when:
-
You have the arguments to construct the object, but not the object itself.
-
The object is expensive to copy.
-
The object has a non-explicit constructor that takes the same arguments as you want to pass to emplace_back
⚡
Use emplace_back when building an element in place
When we need to build an object straight inside the container, we
should use emplace_back()
since it will directly generate an object
within the container, eliminating the need for a move/copy()
.
struct Test {
int a, b;
Test(int x, int y) : a(x), b(y) {}
};
std::vector<Test> v1;
std::vector<Test> v2;
auto start = std::chrono::high_resolution_clock::now();
// ----------------------------------------------------------------------
for (int i = 0; i < 1000000; ++i) {
v1.push_back(Test(i, i));
}
// ----------------------------------------------------------------------
auto end = std::chrono::high_resolution_clock::now();
auto duration_push_back =
std::chrono::duration_cast<std::chrono::microseconds>(end - start)
.count();
start = std::chrono::high_resolution_clock::now();
// ----------------------------------------------------------------------
for (int i = 0; i < 1000000; ++i) {
v2.emplace_back(i, i);
}
// ----------------------------------------------------------------------
end = std::chrono::high_resolution_clock::now();
auto duration_emplace_back =
std::chrono::duration_cast<std::chrono::microseconds>(end - start)
.count();
fmt::print("{:12} took {:5} microseconds\n", "push_back", duration_push_back);
fmt::print("{:12} took {:5} microseconds\n", "emplace_back",
duration_emplace_back);
return 0;
Possible output
push_back took 64319 microseconds
emplace_back took 37047 microseconds