当T是基本类型时,std :: vector <t> :: clear()的复杂性是什么?</t>

时间:2012-06-27 23:03:11

标签: vector complexity-theory clear primitive unordered-map

我知道clear()操作的复杂性在容器的大小上是线性的,因为必须调用析构函数。但是原始类型(和POD)呢?似乎最好的做法是将矢量大小设置为0,这样复杂性就是恒定的。

如果可以,std :: unordered_map也可以吗?

2 个答案:

答案 0 :(得分:7)

  

似乎最好的办法是将矢量大小设置为0,这样复杂性就是不变的。

通常,resizing a vector to zero的复杂性与vector中当前存储的元素数量呈线性关系。因此,将vector的大小设置为零并不比调用clear()更有优势 - 两者基本相同。

但是,至少有一个实现(libstdc ++,bits/stl_vector.h中的源代码)通过使用部分模板特化为您提供原始类型的O(1)复杂度。

clear()的实现导航到bits/stl_construct.h中的std::_Destroy(from, to)函数,该函数执行非平凡的编译时优化:它声明了一个辅助模板类{{1}使用类型_Destroy_aux的模板参数。该类具有bool部分特化true显式特化。这两个特化都定义了一个名为false的静态函数。如果模板参数为__destroy,则函数体为空;如果参数为true,则body contains a loop invoking T's destructor可以通过调用false

诀窍来自line 126

std::_Destroy(ptr)

根据std::_Destroy_aux<__has_trivial_destructor(_Value_type)>:: __destroy(__first, __last); 检查的结果实例化辅助类。对于内置类型,检查器返回__has_trivial_destructor,对于具有非平凡析构函数的类型,返回true。结果,对false的调用成为__destroyint和其他POD类型的无操作。

doublestd::unordered_map的不同之处在于它可能需要删除表示POD对象的“哈希桶”的结构,而不是删除对象本身 * vectorclear的优化是可能的,但它在很大程度上取决于实现,所以我不会指望它。


* 确切的答案取决于实现:基于开放寻址(线性探测,二次探测等)实现collision resolution的哈希表可能能够删除{中的所有桶{1}};但是,基于单独链接的实现必须逐个删除存储桶。

答案 1 :(得分:0)

gcc的std::_Destroy版本,这是clear()最终使用的版本,尝试模拟该类型是否具有普通的析构函数,因此在这种情况下,即使没有优化,复杂性也是不变的通过。但是我不知道模板的效果如何。