【问题标题】:Is `std::vector<primitive>::clear()` a constant time operation?`std::vector<primitive>::clear()` 是恒定时间操作吗?
【发布时间】:2013-02-20 00:41:28
【问题描述】:

在向量上调用clear() 将调用存储在向量中的任何内容的析构函数,这是一个线性时间操作。但是当向量包含像intdouble这样的原始类型时,情况是否如此?

【问题讨论】:

标签: c++ vector stl


【解决方案1】:

我相信答案取决于实现。它需要最多线性时间,但某些实现可能会选择对此进行优化。

根据“Does clearing a vector affect its capacity?”,MSVC 和 G++ 都不会降低其向量的容量,即使在调用 .clear 时也是如此。查看 G++ 标头,很明显.clear 是具有默认分配器的常量时间,只要元素是标量(原始算术类型或指针)。

【讨论】:

  • 这似乎与我在标准中找不到任何关于 vector::clear() (或序列容器的 clear() )的事实一致。当然,这可能是我没有正确搜索...
  • @juanchopanza:我查看了规范,它确实看起来确实是be missing。但请注意,erase(begin(), end()) 指定的时间等于调用每个析构函数所需的时间。
【解决方案2】:

从如何实现vector 的观点考虑这一点。当你调用时:

 delete [] internalPtr;

会发生什么?

  • 堆必须回收一块连续的空间
  • 析构函数必须触发 internalPtr 中的每个对象

对于原始类型,前者仍然必须发生,但它们不存在析构函数。所以delete[] 将完全根据堆删除内存块的速度来执行

【讨论】:

  • 至少使用默认分配器,std::vector不会使用delete [] internalPtr;
【解决方案3】:

在此链接中:

http://www.cplusplus.com/reference/vector/vector/clear/

它说clear() 的复杂性在大小上是线性的(破坏)。

【讨论】:

  • 我实际上在 C++11 标准中找不到任何东西来支持这一点。链接可能有误。
【解决方案4】:

嗯.. 它说 clear() 是线性的,但我们也知道它调用每个项目的析构函数...

http://www.cplusplus.com/reference/vector/vector/clear/

如果析构函数调用不是线性的怎么办?

但是,在原语上,析构函数调用是线性的(或恒定的,这并不重要,除非它不超过线性)

所以是的,在原语上是 clear() 总是一个线性操作

【讨论】:

  • 哪里说它是线性的?我在 C++11 标准的任何地方都找不到它,但我可能会遗漏一些东西。
  • OP 专门询问具有微不足道的析构函数的原语。
  • @juanchopanza 和 nneonneo 已修复
猜你喜欢
  • 2022-12-14
  • 1970-01-01
  • 2016-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-04
  • 2020-11-19
  • 1970-01-01
相关资源
最近更新 更多