哪一个使用擦除或在向量中调整大小更快?

时间:2014-02-17 11:35:45

标签: c++ optimization vector resize erase

在下面的代码中哪一个更有效调用resize或erase?

vector<int> a(5000);
//....
vector<int>::iterator it = remove(a.begin(),a.end(),8)

a.resize( std::distance(a.begin(),it));
//or 
a.erase(it,a.end());

我认为这取决于重复元素的数量对吗?

3 个答案:

答案 0 :(得分:5)

重复的数量相等,它们具有相同的复杂性。收缩向量时,resize是根据erase

定义的

n3337,23.3.6.3 说:

  

void resize(size_type sz);

     

9效果:如果sz <= size(),相当于erase(begin() + sz, end()); 。 [...]

答案 1 :(得分:2)

剖析器说什么?这显然可以从一个变化 实施到另一个(虽然只是一个常数 因素 - 要求复杂性相同)。

就此而言:剖析器显示你失去了太多 在这儿吗?写这个的惯用方法是:

a.erase( std::remove( a.begin(), a.end(), 8 ), a.end() );

除非剖析器清楚地说这是一个瓶颈,否则你 应该以惯用的方式编写它,以便C ++程序员 立即认识到发生了什么,不要浪费时间 认识到你正在做同样的事情,并想知道为什么 你没有以惯用的方式做到这一点。

答案 2 :(得分:1)

  

“我认为这取决于重复元素的数量对吗?”

不。 int没有析构函数,因此1个重复或1000个没有区别。所有函数需要做的是设置正在使用的元素的新结束的内部记录。因此,remove()的效果在此处是代价高昂的,而不是resize / erase。 (即使有一个析构函数,它们也会循环调用它的相同数量的元素,几乎完全相同的时间)。

你几乎总是可以信任任何经验丰富的标准库实现,不要做一些愚蠢的事情,并且花费的时间远远超过必要的时间,所以鉴于行为是相同的 - 每个jrok的答案 - 除非你的探查者告诉你,否则没有理由进一步调查到。

  • 他们这样做并且不更新某些“大小”成员不是标准规定的,但我实际看到的每个实现都存储了一个“结束”指针,这是有意义的,因为它支持iter != v.end()迭代器实现为指针而没有end()的较慢的开始+大小算术计算,也没有同样丑陋的特殊外壳,因此递增end-1迭代器会产生一些哨兵状态。