I am currently reading Scott Meyer's "Effective Modern C++". In Item 42, he claims that e.g. an std::vector::emplace_back
is usually, but not always, as fast as or even faster than using push_back
. He lists three conditions under which it should be at least as fast, but does not provide a counterexample in the case where these conditions are not all satisfied.
Can someone provide me with an example where using emplace_back
would be expected to result in strictly worse performance than using push_back
?

- 8,220
- 2
- 26
- 45

- 1,569
- 1
- 11
- 21
-
It's not really the same thing, but you can't use `emplace_back` for a braced initializer (e.g., calling a list constructor like `vecOfVecs.emplace_back({1, 2, 3});`), so I guess that would make it not as fast as `push_back`. – chris Oct 05 '15 at 05:20
-
8`He lists three conditions` which are? – user657267 Oct 05 '15 at 06:52
-
1It would be a really obscure and odd circumstance if `emplace_back` is actually *slower*. It's normally same or better. – sp2danny Oct 05 '15 at 13:47
-
Scott Meyers refers to this exact question in his keynote talk @ Meeting C++ 2014 [here](https://www.youtube.com/watch?v=smqT9Io_bKo&t=18m25s). Enjoy. – Amir Kirsh Feb 16 '21 at 17:17
3 Answers
It depends on what you mean by "emplace_back
is slower than push_back
". Considering class that is expensive to construct and cheap to copy, for example class with copy-on-write behavior, or class representing hash value:
class Hash {
public:
int value;
Hash(const char *data) : value(very_expensive_hash_function(data)) {} // expensive
Hash(const Hash &other) : value(other.value) {} // cheap
};
Hash h(foo);
std::vector<Hash> v;
v.push_back(h); // 1
v.emplace_back("foo"); // 2
Then, (1) will be indeed faster than (2). However, such comparision is not fair. When comparing performance, costs of constructors involved should be factored in.

- 18,889
- 4
- 46
- 89
Silly example:
std::vector<always_throws_on_construction> vec;
if(vec.size() == vec.capacity())
{
vec.push_back(always_throws_on_construction());
}
would probably be faster than
std::vector<always_throws_on_construction> vec;
if(vec.size() == vec.capacity())
{
vec.emplace_back();
}

- 9,468
- 25
- 44
-
-
@black In the push back case, you throw an exception before you run any vector code. In the emplace back case you dynamically expand the vector to be able to handle the new element and then throw. Like I said, its a silly example. [edited to be clear an exception is thrown] – Mike Vine Oct 05 '15 at 13:16
-
Oh yeah. For some reason I thought you were saying the opposite, that's why I asked. – edmz Oct 05 '15 at 13:36
Essentially this boils down to std implementations. Theoretically, emplace should always be as fast or faster, except the reality is that no standard library implementation takes full advantage of that.
He gave a talk on this exact issue a few years ago: https://www.youtube.com/watch?t=3427&v=smqT9Io_bKo
Check out the first 1 hour of the talk for a more detailed explanation. The Q&A at the end of the talk is relevant as well.

- 308
- 1
- 8