【发布时间】:2017-11-03 17:37:19
【问题描述】:
当容量无法预测时,我正在尝试加速 vector::push_back
当保留可用时,向量 push_back 将新元素写入容器的末尾,然后移动结束标记。使用完所有预留后,push_back 可能会触发重新分配,这是一个缓慢的过程。
为了加快速度,reserve 会为几个即将到来的 push_back 重新生成,而不会在空时重新分配。您认为此代码如何有助于实现该目标?
#ifndef __VECTOR_HPP
#define __VECTOR_HPP
#include <exception>
#include "Concept.hpp" //Concept::RESA constant
#include <vector>
template <typename T>
class Vector : public std::vector<T> {
public :
void push_back (T t) {
if (std::vector<T>::size () == std::vector<T>::capacity ()) {
std::vector<T>::reserve ((size_t) Concept::RESA);
}
std::vector<T>::push_back (t);
}
};
#endif
测试程序:
#include "Vector.hpp"
int main (int argc, char* argv []) {
{
std::vector<size_t> v0;
clock_t t (clock ());
size_t duration (0);
for (size_t i (0); i != 10000000; i++) {
v0.push_back (i);
}
duration = (size_t) (clock () -t);
std::cout << "duration old push_back == " << duration << " ticks" << std::endl;
}
{
size_t duration (0);
Vector<size_t> v1;
clock_t t (clock ());
for (size_t i (0); i != 10000000; i++) {
v1.push_back (i);
}
duration = (size_t) (clock () -t );
std::cout << "duration new push_back == " << duration << " ticks" << std::endl;
}
}
结果:
使用 Concept::RESA == 8192 并应用建议,以下是 Lenovo ThinkCentre icore5(Linux Debian,g++)上的结果:
duration old push_back == 105317 tick
新 push_back 持续时间 == 87156 滴答声
【问题讨论】:
-
你到底想用这段代码实现什么?
-
问题陈述是什么?
-
@WhozCraig 直接以恒定增量调用 reserve 将使插入 O(n^2)。通过插入,他仍然获得指数增长,因为它是由 std::vector 处理的。但这并没有改变这样一个事实,即这段代码不仅毫无意义,而且做了一些他认为不应该做的事情。
-
我试图解决这个问题,但当我意识到糟糕的措辞与对
std::vector的糟糕理解相匹配时,我就回滚了。解决问题使其毫无意义。特别是,虽然第二句谈到“reserve is available”,但这确实not 表示vector::reserve。这可能意味着vector::capacity() greater than vector::size()。 -
@Ap31:我想我明白你的意思了。我想 OP 的结果评论是向量的结果重新分配不会是
resa_.begin()和resa_.end()之间的距离,但无论vector的重新分配策略是什么(可能是基础缓冲区的简单加倍)