向量的性能问题

时间:2014-03-02 12:42:18

标签: c++ vector stl

我在代码中使用了几个结构。第一个结构是在从一行文本文件中读取数据后构造的,第二个结构包含一个第一类结构的向量。

 struct A{
       long a, b, c, d, e, f;
       string x, y, z;
 }

 struct B{
       string id1;
       vector<A> aVec;
 }

现在我读取了我的文件并初始化了一个struct B的向量。然后根据传入的新行的id1和id2是什么,我创建一个新的A并将其推入正确的B.

 vector<B> bVec;
 vector<A> atmpVec;
 B btmp;
 //Initializing bVec
 for(int i = 0; i < 7; i++)
 {
     btmp.id1 = "c"+to_string(i);
     btmp.aVec = atmpVec;
     //tried using reserve too.
     //btmp.aVec.reserve(50000);

     bVec.push_back(btmp);
 }
 //readerCode
 while(getline(file, line))
 {
      A = readA(line); //readA reads and sets the fields of struct A.
      int idx = getBIdx(bVec, A); //getBIdx returns which B struct should i be using.
      bVec[idx].aVec.push_back(A);
 }

现在最后一行已成为瓶颈。如果我只是声明A的向量并继续推回它,则处理一百万条记录所需的时间约为10秒。 另一方面,使用这种方法,处理50k记录需要60秒。 有没有办法保持上述一般结构而不会失去性能。 有效实现这个的任何方法吗?

3 个答案:

答案 0 :(得分:0)

不是花在getBIdx方法上的时间吗?推动单个向量或N之间的向量应该几乎相同。

尝试使用简单的getBIdx:

#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>

#include <time.h>

using namespace std;

const int NUMBER_OF_A = 3E7;
const int NUMBER_OF_B = 7;

struct A {
  long a, b, c, d, e, f;
  string x, y, z;
};

struct B {
  string id1;
  vector<A> aVec;
};

struct A readA() {
  A a;
  a.a = 1;
  a.b = 2;
  return a;
}

int getBIdx(const A& a) {
  return rand() % NUMBER_OF_B;
}

void Test1() {
  vector<B> bVec;
  for(int i = 0; i < NUMBER_OF_B; i++) {
    B btmp;
    bVec.push_back(btmp);
  }
  for(int i = 0; i < NUMBER_OF_A; ++i) {
    A a = readA();
    int idx = getBIdx(a);
    bVec[idx].aVec.push_back(a);
  }
}

void Test2() {
  vector<A> vector;

  for(int i = 0; i < NUMBER_OF_A; ++i) {
    A a = readA();
    int idx = getBIdx(a);
    vector.push_back(a);
  }
}

int main() {
  time_t start = time(0);
  Test1();
  time_t end_of_test1 = time(0);
  Test2();
  time_t end_of_test2 = time(0);

  cout << "Elapsed test 1:" << end_of_test1 - start << " s" << endl;
  cout << "Elapsed test 2:" << end_of_test2 - end_of_test1 << " s" << endl;
  return 0;
}

结果:(旧的奔腾4单核机)

Elapsed test 1:17 s
Elapsed test 2:13 s

所以它的速度较慢,但​​速度并不慢。

使用-O3时,差异甚至更小:

Elapsed test 1:9 s
Elapsed test 2:7 s

答案 1 :(得分:0)

我会尝试以两种方式优化此代码

  1. 定义vector<A*> aVec而不是vector<A> aVec,以避免复制构造函数调用,因为您使用的是C ++ 0x

  2. 估计B中aVec大小的大小,使用resize()重新设置一些空间可能会节省一些时间

答案 2 :(得分:0)

你应该在bVec上使用大小构造函数,因为它的大小是已知的。 然后,你可能是用A矢量填充它的主要罪魁祸首 想在bVec中的每个avec上使用vector :: reserve,具有任意大小,具体取决于你要输入的数据量。

另外,你确定用-O3编译吗?