快速推送矢量多次的方法

时间:2016-10-08 19:25:35

标签: c++ vector

我已经确定了我的c ++代码中的瓶颈,我的目标是加快速度。如果条件为真,我将项目从一个向量移动到另一个向量。

在python中,这样做的pythonic方法是使用列表解析:

my_vector = [x for x in data_vector if x > 1]

我已经破解了一种在C ++中执行此操作的方法,并且它运行正常。但是,我在一个while循环中调用了数百万次,而且速度很慢。我对内存分配了解不多,但我认为我的问题与使用push_back重新分配内存有关。有没有办法以不同的方式分配我的内存来加速这段代码? (在my_vector - 循环完成之前,我不知道for应该有多大。

std::vector<float> data_vector;
// Put a bunch of floats into data_vector
std::vector<float> my_vector;

while (some_condition_is_true) {
    my_vector.clear();
    for (i = 0; i < data_vector.size(); i++) {
        if (data_vector[i] > 1) {
            my_vector.push_back(data_vector[i]);
        }
    }
    // Use my_vector to render graphics on the GPU, but do not change the elements of my_vector 
    // Change the elements of data_vector, but not the size of data_vector
}

5 个答案:

答案 0 :(得分:7)

使用std::copy_if,并最初为data_vector.size()保留my_vector(因为这是谓词可以评估为true的最大元素数量):

std::vector<int> my_vec;
my_vec.reserve(data_vec.size());
std::copy_if(data_vec.begin(), data_vec.end(), std::back_inserter(my_vec),
    [](const auto& el) { return el > 1; });

请注意,如果您希望谓词评估为true的次数远小于reserve的大小,则可以避免此处data_vector调用。

答案 1 :(得分:1)

运行代码两次,第一次只计算,你需要多少新元素。然后使用reserve已经分配了所需的所有内存。

while (some_condition_is_true) {
    my_vector.clear();
    int newLength = 0;
    for (i = 0; i < data_vector.size(); i++) {
        if (data_vector[i] > 1) {
            newLength++;
    my_vector.reserve(newLength);

    for (i = 0; i < data_vector.size(); i++) {
        if (data_vector[i] > 1) {
            my_vector.push_back(data_vector[i]);
        }
    }
    // Do stuff with my_vector and change data_vector
}

答案 2 :(得分:1)

我怀疑分配my_vector是个问题,特别是如果while循环执行多次,因为my_vector的容量应该很快就足够了。

但是要确保您可以在my_vector中保留与data_vector相对应的容量:

my_vector.reserve(data_vector.size());

while (some_condition_is_true) {
    my_vector.clear();
    for (auto value : data_vector) {
      if (value > 1)
          my_vector.push_back(value);
    }
}

答案 3 :(得分:1)

如果您使用的是Linux,则可以为my_vector保留内存,以防止std::vector重新分配,这是您案例中的瓶颈。请注意,由于过度使用,保留不会浪费内存,因此保留值的任何粗略估计值都将满足您的需求。在您的情况下,data_vector的大小就足够了。 while循环之前的这行代码应该解决瓶颈问题:

my_vector.reserve(data_vector.size());

答案 4 :(得分:1)

虽然其他人为您的查询发布了各种优秀的解决方案,但似乎对内存分配仍然没有太多解释,您不太了解,所以我想与您分享我对此主题的了解。希望这会有所帮助。

首先,在C ++中,有几种类型的内存:stackheapdata segment

Stack用于局部变量。有一些与之相关的重要功能,例如,它们将被自动解除分配,对它的操作非常快,其大小取决于操作系统,并且很小,因此在stack中存储一些KB数据可能会导致内存溢出等等。

Heap的内存可以全局访问。至于它的重要特性,我们有,它的大小可以根据需要动态扩展,其大小更大(远大于stack),对它的操作比stack慢,手动释放内存是需要(在现今的操作系统中,内存将在程序结束时自动释放),等等。

Data segment用于全局变量和静态变量。事实上,这块存储器可以分成更小的部分,例如BBS。

在您的情况下,使用vector。实际上,vector的元素存储在其内部动态数组中,即具有动态数组大小的内部数组。在早期的C ++中,可以在stack内存上创建动态数组,但是,不再是这种情况。要创建动态数组,必须在heap上创建它。因此,vector的元素存储在heap上的内部动态数组中。实际上,要动态增加数组的大小,需要一个进程memory reallocation。但是,如果vector用户不断扩大他或她的vector,那么reallocation费用的间接费用将会很高。为了解决这个问题,vector首先会分配一块大于当前需求的内存,即分配内存以备将来使用。因此,在您的代码中,每次调用memory reallocation时都不会执行push_back()。但是,如果要复制的vector非常大,则为将来使用而保留的内存将不足。然后,memory allocation将会发生。要解决这个问题,可以使用vector.reserve()

我是新手。希望我在分享时没有犯错。 希望这会有所帮助。