C++清除或擦除矢量的最快方法

use*_*171 36 c++ performance vector clear

我有一个代码,我常规填充0到5000个元素之间的向量.我知道最大值永远不会超过5000.而不是多次初始化矢量,我只想做一次

vector<struct> myvector;
myvector.reserve(5000);
Run Code Online (Sandbox Code Playgroud)

但是,为了再次填充向量,我必须首先清除向量而不改变其容量.所以通常我会调用myvector.clear();

这是O(n)操作.有什么简单的我可以做到提高这个的性能,还是这是最好的?

Vau*_*ato 39

如果你的结构有一个非平凡的析构函数,那么需要为向量的所有元素调用它,而不管它是如何被清空的.如果你的struct只有一个简单的析构函数,那么允许编译器或标准库实现优化掉销毁过程并给你一个O(1)操作.


Dav*_*eas 24

成本主要clear()取决于存储的对象是什么,特别是它们是否具有普通的析构函数.如果类型没有一个简单的析构函数,那么调用必须销毁所有存储的对象,它实际上是一个O(n)操作,但你不能真正做更好的事情.

现在,如果存储的元素具有普通的析构函数,那么实现可以优化成本,并clear()成为廉价的O(1)操作(只需重置大小 - end指针).

请记住,要了解渐近复杂性,您需要知道它所谈论的内容.在clear()它的情况下,它表示被调用的析构函数的数量,但如果成本(隐藏)为0,则操作是无操作.

  • 我认为在这种情况下,"琐碎的析构函数"与"无析构函数"相同. (8认同)
  • @ user788171:您可能想阅读[什么是聚合和POD以及它们如何/为什么特殊?](http://stackoverflow.com/a/7189821/2070725)以了解这整个"琐碎"的东西是什么约(向下滚动以达到"琐碎"部分). (4认同)
  • 你能澄清什么是平凡的析构函数吗?我不熟悉这个术语。 (2认同)
  • @MatsPetersson:嗯......有点复杂,但这就是主意.基本上类型不能有用户提供的析构函数(你说的),它不能有任何虚函数或基础,并且所有成员和基础也必须有简单的析构函数(即没有成员将具有虚函数/库或用户提供的析构函数) (2认同)
  • @JamesKanze:是的,这是可能的,我希望它甚至是通用的(尚未对此进行测试,但它在 1995 年的“C++ 对象模型”中作为优化提到,所以我希望它是*通用的* )。但我正在考虑一些库在库级别所做的事情(即使没有优化):通过特征检测该类型是否具有微不足道的析构函数并使用甚至不调用构造函数的实现(即首先没有要优化的内容) . (2认同)

Jer*_*fin 10

你做删除Vector中的现有项目有什么需要(可能)调用被破坏的每个项目的析构函数.因此,从容器的角度来看,您可以期待的最好的是线性复杂性.

这只留下了你在矢量中存储什么类型的项目的问题.如果您存储类似的东西int,编译器可以/将提前知道没有析构函数可以调用,那么删除最终会导致复杂性不变的可能性至少相当不错.

但是,我怀疑改变语法(例如,clear()vs. resize()vs. erase(begin(), end()))将会产生任何重大差异.语法不会改变(在没有线程的情况下)调用N个析构函数的事实是O(N)操作.