shrink_to_fit() vs 交换技巧
shrink_to_fit() vs swap trick
我有一个游戏,其中某些游戏对象会一次性生成,然后在获得 destroyed/killed 时消失。游戏对象是 std::vector
中的元素,我想尽量减少内存使用。我已经习惯了交换技巧,
std::vector<gameObject>(gameObjectVector.begin(), gameObjectVector.end()).swap(gameObjectVector);
但我注意到 C++11 中内置的 shrink_to_fit()
。然而,它具有线性复杂度,而交换技巧是恒定的。交换技巧不是在各个方面都优越吗?
交换技巧实际上并不是恒定时间的。执行实际交换的成本确实是 O(1),但是还有 std::vector
析构函数触发和清理所有分配的 space 的成本。如果底层对象具有非平凡的析构函数,那可能会花费 Ω(n),因为 std::vector
需要去调用那些析构函数。还有为存储在初始向量中的所有元素调用复制构造函数的成本,这与 Ω(n) 类似。
因此,这两种方法应该具有大致相同的复杂性,只是 shrink_to_fit
更清楚地传达了意图并且可能更适合编译器优化。
isocpp.org 上的已接受答案是错误的。
shrink_to_fit
是 nonbinding 要求。
我个人认为 ISO 将其保留为非强制性的(没有对发生的事情提供更强有力的保证)是愚蠢的,因为它令人困惑,但也许他们有充分的理由 (tm)。
我有一个游戏,其中某些游戏对象会一次性生成,然后在获得 destroyed/killed 时消失。游戏对象是 std::vector
中的元素,我想尽量减少内存使用。我已经习惯了交换技巧,
std::vector<gameObject>(gameObjectVector.begin(), gameObjectVector.end()).swap(gameObjectVector);
但我注意到 C++11 中内置的 shrink_to_fit()
。然而,它具有线性复杂度,而交换技巧是恒定的。交换技巧不是在各个方面都优越吗?
交换技巧实际上并不是恒定时间的。执行实际交换的成本确实是 O(1),但是还有 std::vector
析构函数触发和清理所有分配的 space 的成本。如果底层对象具有非平凡的析构函数,那可能会花费 Ω(n),因为 std::vector
需要去调用那些析构函数。还有为存储在初始向量中的所有元素调用复制构造函数的成本,这与 Ω(n) 类似。
因此,这两种方法应该具有大致相同的复杂性,只是 shrink_to_fit
更清楚地传达了意图并且可能更适合编译器优化。
isocpp.org 上的已接受答案是错误的。
shrink_to_fit
是 nonbinding 要求。
我个人认为 ISO 将其保留为非强制性的(没有对发生的事情提供更强有力的保证)是愚蠢的,因为它令人困惑,但也许他们有充分的理由 (tm)。