Examples where std::vector::emplace_back is slower

2019-05-07 01:44发布

问题:

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?

回答1:

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();
}


回答2:

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.