STL向量是否可以“重置”,以便在可能的情况下重用相同的内存?

时间:2014-07-09 14:20:51

标签: c++ vector stl

通常,在模拟中,我发现我需要有一个可能很大的向量,它可以从迭代到迭代完全重写,但每次都不是完全相同的大小。我不想每次都重新分配内存,但我也不知道确切的大小。

基本上,我想要这种行为:

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%,这对我来说已经足够了。

0 个答案:

没有答案