std::vector::emplace_back比std::vector::push_back慢的例子

Examples where std::vector::emplace_back is slower than std::vector::push_back?

本文关键字:std back vector push emplace      更新时间:2023-10-16

我最近在读Scott Meyer的《Effective Modern c++》。在第42项中,他声称,例如,std::vector::emplace_back通常(但并不总是)与push_back一样快,甚至更快。他列出了至少应该达到同样速度的三个条件,但没有提供在这些条件不全部满足的情况下的反例。有人能给我提供一个例子,使用emplace_back会导致比使用push_back更差的性能吗?

这取决于你所说的" emplace_backpush_back慢"是什么意思。考虑构造成本高而复制成本低的类,例如具有写时复制行为的类,或表示哈希值的类:

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

那么,(1)确实会比(2)快。然而,这种比较是不公平的。在比较性能时,应将所涉及的构造函数的成本考虑在内。

愚蠢的例子:

std::vector<always_throws_on_construction> vec;
if(vec.size() == vec.capacity())
{
    vec.push_back(always_throws_on_construction());
}

可能比

std::vector<always_throws_on_construction> vec;
if(vec.size() == vec.capacity())
{
    vec.emplace_back();
}

本质上这归结为std实现。理论上,emplace应该总是一样快或更快,但现实是没有标准库实现充分利用了这一点。

几年前他就这个问题做过一次演讲:https://www.youtube.com/watch?t=3427&v=smqT9Io_bKo

查看前1个小时的演讲以获得更详细的解释。讲座最后的问答也是相关的。