通常,在模拟中,我发现我需要有一个可能很大的向量,它可以从迭代到迭代完全重写,但每次都不是完全相同的大小。我不想每次都重新分配内存,但我也不知道确切的大小。
基本上,我想要这种行为:
struct reusable_vec{
std::vector<int> v;
int actual_size;
reusable_vec(){actual_size=0;}
void push_back(int val){
if (v.size() < actual_size){
v.push_back(val);
} else {
v[actual_size]=val;
}
actual_size++;
}
int &operator[](int index){
if (index < actual_size){
return v[index];
} else {
throw invalid_argument("I'm sorry, Dave. I'm afraid I can't do that.");
}
}
void reset(){ actual_size=0;}
};
此时我可以将矢量填充到任何大小,重置它并重复使用相同的对象,而不必弄乱内存。我会记住记忆,但无论如何,我每回合都可能需要几乎那么多记忆。令人讨厌的是,我必须重新实现任何使用大小的STL向量例程...
这似乎应该以某种方式构建到STL中,但是看一下文档,我无法弄清楚如何获得这种行为。
编辑:清除后push_back的时间惩罚。在评论之后,我尝试了clear()
。它做了我想做的事情,除了我需要重新分配内存(几乎与第一次一样多的时间成本。
#include <vector>
#include <iostream>
#include <ctime>
#include <cassert>
int main(){
int N=10000000;
std::vector<int> v;
auto start = std::clock();
for (int i = 0; i<N; i++)
v.push_back(rand());
auto t1 = std::clock();
std::cout << "push_back time: " << (t1 - start) / (double)(CLOCKS_PER_SEC / 1000) << " ms" << std::endl;
v.clear();
start = std::clock();
std::cout << "clear time: " << (start - t1) / (double)(CLOCKS_PER_SEC / 1000) << " ms" << std::endl;
for (int i = 0; i<N; i++)
v.push_back(rand());
t1 = std::clock();
std::cout << "push_back after clear time: " << (t1 - start) / (double)(CLOCKS_PER_SEC / 1000) << " ms" << std::endl;
v.resize(0);
start = std::clock();
std::cout << "resize(0) time: " << (start - t1) / (double)(CLOCKS_PER_SEC / 1000) << " ms" << std::endl;
for (int i = 0; i<N; i++)
v.push_back(rand());
t1 = std::clock();
std::cout << "push_back after resize(0) time: " << (t1 - start) / (double)(CLOCKS_PER_SEC / 1000) << " ms" << std::endl;
for (int i = 0; i<N; i++)
v[i] = rand();
start = std::clock();
std::cout << "in_place time: " << (start - t1) / (double)(CLOCKS_PER_SEC / 1000) << " ms" << std::endl;
assert(v.size() == N);
return 0;
}
在我的普通英特尔(R)Core(TM)i3-2350M CPU @ 2.30GHz上,我得到:
push_back time: 526.776 ms
clear time: 0.121 ms
push_back after clear time: 445.08 ms
resize(0) time: 0.034 ms
push_back after resize(0) time: 445.136 ms
in_place time: 160.944 ms
第1课,clear()
和resize(0)
对于整数来说非常快,毫无疑问。第2课,在clear()
之后推回需要花费几乎同样多的时间来推回原处的向量(我的目标是上面的reusable_vec
)是快3倍。
使用-O2
编译:
push_back time: 226.505 ms
clear time: 0.117 ms
push_back after clear time: 145.651 ms
resize(0) time: 0.034 ms
push_back after resize(0) time: 145.561 ms
in_place time: 127.776 ms
第0课,总是用优化编译! resize(0)
和clear()
大致相同。但是,第二轮push_back
s比现场慢了14%,这对我来说已经足够了。