C++:使用矢量/数组优化速度?

Joh*_*ith 12 c++ vector

我有一个嵌套的for循环结构,现在我在每次迭代开始时重新声明向量:

void function (n1,n2,bound,etc){

    for (int i=0; i<bound; i++){
             vector< vector<long long> > vec(n1, vector<long long>(n2));
             //about three more for-loops here
    }
}
Run Code Online (Sandbox Code Playgroud)

这允许我在每次迭代时"重新开始",这很有效,因为我的内部操作主要是以vec [a] [b] + =某个值的形式.但我担心大n1或大n2的速度很慢.我不知道vector/arrays/etc的底层架构,所以我不确定处理这种情况的最快方法是什么.我应该使用数组吗?我应该以不同方式清除它吗 我应该完全不同地处理逻辑吗?

编辑:矢量的大小在技术上不会改变每次迭代(但它可能会根据函数参数而改变).我只是试图清除它/ etc,因此在所有其他情况下,程序的速度与人类一样快.

编辑:

我的不同方法的结果:

Timings (for a sample set of data):
reclaring vector method: 111623 ms
clearing/resizing method: 126451 ms
looping/setting to 0 method: 88686 ms
Run Code Online (Sandbox Code Playgroud)

Kon*_*lph 12

我明确偏爱小范围(即如果只在那里使用,则在最内层循环中声明变量)但是对于大尺寸,这可能会导致大量分配.

因此,如果此循环是性能问题,请尝试在循环外声明变量并仅在循环内清除它 - 但是,这仅在向量的(保留)大小保持相同时才有利.如果要调整向量的大小,那么无论如何都会得到重新分配.

不要使用原始数组 - 它不会给你带来任何好处,只会带来麻烦.


Jam*_*ter 10

以下是一些测试几种不同方法的代码.

#include <chrono>
#include <iostream>
#include <vector>

int main()
{
  typedef std::chrono::high_resolution_clock clock;

  unsigned n1 = 1000;
  unsigned n2 = 1000;

  // Original method
  {
    auto start = clock::now();
    for (unsigned i = 0; i < 10000; ++i)
    {
      std::vector<std::vector<long long>> vec(n1, std::vector<long long>(n2));
      // vec is initialized to zero already

      // do stuff
    }
    auto elapsed_time = clock::now() - start;

    std::cout << elapsed_time.count() << std::endl;
  }


  // reinitialize values to zero at every pass in the loop
  {
    auto start = clock::now();
    std::vector<std::vector<long long>> vec(n1, std::vector<long long>(n2));
    for (unsigned i = 0; i < 10000; ++i)
    {
      // initialize vec to zero at the start of every loop
      for (unsigned j = 0; j < n1; ++j)
        for (unsigned k = 0; k < n2; ++k)
            vec[j][k] = 0;

      // do stuff
    }
    auto elapsed_time = clock::now() - start;

    std::cout << elapsed_time.count() << std::endl;
  }

  // clearing the vector this way is not optimal since it will destruct the
  // inner vectors
  {
    auto start = clock::now();
    std::vector<std::vector<long long>> vec(n1, std::vector<long long>(n2));
    for (unsigned i = 0; i < 10000; ++i)
    {
      vec.clear();
      vec.resize(n1, std::vector<long long>(n2));

      // do stuff
    }
    auto elapsed_time = clock::now() - start;

    std::cout << elapsed_time.count() << std::endl;
  }

  // equivalent to the second method from above
  // no performace penalty
  {
    auto start = clock::now();
    std::vector<std::vector<long long>> vec(n1, std::vector<long long>(n2));
    for (unsigned i = 0; i < 10000; ++i)
    {
      for (unsigned j = 0; j < n1; ++j)
      {
        vec[j].clear();
        vec[j].resize(n2);
      }

      // do stuff
    }
    auto elapsed_time = clock::now() - start;

    std::cout << elapsed_time.count() << std::endl;
  }
}
Run Code Online (Sandbox Code Playgroud)

编辑:我已经更新了代码,以便在方法之间进行更公平的比较. 编辑2:稍微清理一下代码,方法2或4是要走的路.

以下是我的计算机上面四种方法的时间:

16327389
15216024
16371469
15279471
Run Code Online (Sandbox Code Playgroud)

关键是你应该尝试不同的方法并分析你的代码.

  • downvoter可以解释这有什么问题吗? (4认同)

小智 6

选择容器时,我通常使用此图表来帮助我:

在此输入图像描述

资源


除此之外,

像之前发布的那样,如果这导致性能问题,请在for循环之外声明容器,并在每次迭代开始时清除它

  • 图=幸福:D (4认同)