【问题标题】:Why and when to use clear()为什么以及何时使用 clear()
【发布时间】:2021-01-24 02:56:33
【问题描述】:

根据thisclear() 将销毁所有对象,但不会释放内存。此外,当我遇到删除集合中所有元素的必要性时,我发现set.clear() is linear in size (destructions) 的时间复杂度是constant for set.swap()。 (删除向量的所有元素时同样的问题)

那么在这种情况下,我们是不是应该总是在可能的情况下将 swap() 与空的 STL 容器一起使用? 因此 clear() 与空容器交换相比有什么需要和好处。

抱歉,如果这看起来微不足道,但我找不到任何相关信息。 谢谢!

【问题讨论】:

  • 有时(通常在我的情况下)您清除容器并立即开始重新填充它。如果您释放内存,您将重新进行动态分配和重新分配。糟糕。
  • 值得注意的是vectorshrink_to_fit,这比用空容器交换的习语要清楚得多。这个成语来自这个函数之前的时间,但它已经存在了 9 年。
  • shrink_to_fit 的优势是编译器可以忽略你,如果它可以看到保留内存的好处。不幸的是,它也可以无缘无故地忽略您,因此请确保您的标准库实现提供您想要的结果。

标签: c++ vector set std swap


【解决方案1】:

何时使用 clear()

当您想要移除容器的所有元素时。

为什么要使用 clear()

因为它是实现上述目标的最清晰和最有效的方式。

clear() 将销毁所有对象,但不会释放内存。

这是一个理想的功能。它允许clear 快速,并且允许将新元素添加到容器中快速,因为内存已经分配。

如果您想释放内存 - 如果您知道插入新元素需要再次为分配付费,您可以使用shrink_to_fit

我发现 set.clear() 的时间复杂度在大小(破坏)上是线性的,而 set.swap() 的时间复杂度是恒定的。

你忘记了之前空的,现在完整的集合最终必须被销毁。猜猜set的析构函数的复杂度是多少。

集合的大小是线性的。

那么在这种情况下,我们是不是应该尽可能地使用带有空 STL 容器的 swap() 方法?

Swap 引入了额外的不必要的操作,clear 没有这样做,因此效率不高。此外,它并没有清楚地表达意图。

在一般情况下,用交换替换清除没有任何优势。


在极少数情况下,与空容器交换确实有用。例如,如果您需要清除临界区中的容器,那么稍后交换并保留元素的销毁可以减少该临界区的大小。

【讨论】:

    【解决方案2】:

    当然调用swap() 会更快,但除非你有无限的空容器可用,否则最终你将不得不对你已经交换()的项目的容器做一些事情,在这种情况下,你又回到了线性时间内销毁物品。

    这并不意味着swap() 技巧没有用,但是——例如,如果您有一个具有实时线程和非实时线程的程序,您可能会swap()容器在实时线程中,并留给非实时线程稍后执行实际的clear()/items-destruction,这样实时线程就不必花费其有限的时间时间破坏物品。

    【讨论】:

      【解决方案3】:

      swap() 的时间复杂度是恒定的,是的。

      大概您正在考虑与很快超出范围的局部变量进行交换。如果是这种情况,局部变量的析构函数在超出范围时被调用,并且该析构函数的时间复杂度在大小上是线性的,与clear() 相同。因此没有性能优势,而且您要为可读性较差的代码付出代价。

      【讨论】:

        猜你喜欢
        • 2013-06-13
        • 2013-01-05
        • 2017-03-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-12
        • 1970-01-01
        • 2023-03-03
        相关资源
        最近更新 更多