8

v.erase(v.begin(), v.end());

一样快

v.clear();

?

我不关心额外的函数调用等小开销,编译器会内联这些东西。

我问的原因是因为我有如下代码:

v.erase(v.begin(), last_it);

last_it 通常是结束迭代器,但并非总是如此。我知道不是从末尾擦除一个向量是有代价的,因为向量中的后面的元素需要被复制下来。在 last_it 不是结束迭代器(罕见)的情况下,我可以忍受。但是当我基本上想清除向量时,我不想引入这样的开销。所以我考虑这样写我的代码:

if (last_it == v.end())
{
    v.clear();
}
else
{
    v.erase(v.begin(), last_it);
}

我想知道这是否有必要避免擦除整个向量的性能损失。如果没有惩罚,我宁愿保持我的代码清晰并使用单行语句。

4

3 回答 3

8

查看vector的源代码(参考visual studio 2012(下面的代码片段)或SGI(第434行)之一),clear定义为:

void clear() _NOEXCEPT
{   // erase all elements
    erase(begin(), end());
}

所以我想是的。

所以在你的情况下,我不会使用 if 语句,而只是这样做:

v.erase(v.begin(), last_it);
于 2013-09-19T14:09:55.173 回答
8

不用担心这一点,使用erase. 如果您擦除到最后,则不会有任何元素可以向下移动,因此两者之间的性能差异应该很小(如果有的话)。

于 2013-09-19T14:10:20.777 回答
1

问题是您的问题没有单一的答案,因为没有在所有平台上使用的 C++ 标准库的单一实现。该标准唯一指定的是清除操作的算法复杂性。具体来说,对于可简单破坏的类型,它可以是常数时间;对于需要销毁的类型,销毁的数量将是线性的。这是您从 C++ 标准中获得的唯一保证。

标准库通常作为编译器安装的一部分分发,因此像这样的确切实现细节可能因编译器而异。如果您只关心一个编译器版本,您可以想出一个答案,但要认识到,如果您更改平台,它可能会发生变化。

于 2013-09-19T15:10:01.193 回答