2015-10-05 71 views
3

我正在阅读Scott Meyer的“Effective Modern C++”。在第42项中,他声称例如std::vector::emplace_back通常但不总是与使用push_back一样快或甚至更快。他列出了三种条件,至少应该尽可能快,但是在这些条件不能全部得到满足的情况下,不会提供反例。 有人可以提供一个例子,其中使用emplace_back预计会导致严重的性能比使用push_back其中std :: vector :: emplace_back比std :: vector :: push_back慢的示例?

+0

这不是一回事,但不能使用'emplace_back'作为支撑初始化程序(例如,调用像'vecOfVecs.emplace_back({ 1,2,3});'),所以我想这会让它不如'push_back'快。 – chris

+7

'他列出了三个条件? – user657267

+1

如果'emplace_back'实际上*速度较慢*,那将是一个非常隐晦和奇怪的情况。它通常相同或更好。 – sp2danny

回答

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

这种猜测的基本原理是什么? – edmz

+0

@black在推回的情况下,您在运行任何向量代码之前引发异常。在放回来的情况下,您动态地扩展矢量以便能够处理新元素,然后抛出。就像我说的那样,它是一个愚蠢的例子。 [编辑清除异常抛出] –

+0

噢。出于某种原因,我认为你说的是​​相反的,这就是为什么我问。 – edmz

0

这取决于你的意思是 “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)。但是,这种比较是不公平的。在比较性能时,应考虑构造函数的成本。