C++ 向量的性能问题

C++ 向量的性能问题,c++,vector,stl,C++,Vector,Stl,我在代码中使用了几个结构。第一个结构是在从一行文本文件读取数据后构造的,第二个结构包含第一类结构的向量 struct A{ long a, b, c, d, e, f; string x, y, z; } struct B{ string id1; vector<A> aVec; } 结构A{ 长a、b、c、d、e、f; 字符串x,y,z; } 结构B{ 字符串id1; 向量aVec; } 现在我读取文件并初始化结

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

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

 struct B{
       string id1;
       vector<A> aVec;
 }
结构A{ 长a、b、c、d、e、f; 字符串x,y,z; } 结构B{ 字符串id1; 向量aVec; } 现在我读取文件并初始化结构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);
 }
向量bVec;
载体atmpVec;
B btmp;
//初始化bVec
对于(int i=0;i<7;i++)
{
btmp.id1=“c”+到字符串(i);
btmp.aVec=atmpVec;
//我也试过使用保留。
//btmp.aVec.储量(50000);
bVec.推回(btmp);
}
//读码器
while(getline(文件,行))
{
A=readA(line);//readA读取并设置结构A的字段。
int idx=getBIdx(bVec,A);//getBIdx返回应该使用的B结构。
bVec[idx].aVec.push_-back(A);
}
现在最后一条线已经成为瓶颈。如果我简单地声明一个向量a并继续向后推,处理一百万条记录所需的时间大约为10秒。 另一方面,使用这种方法,只需60秒即可处理50k条记录。 有没有一种方法可以在不损失性能的情况下保持上述总体结构。
有什么方法可以有效地实现这一点吗?

花在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;
}
所以它比较慢,但不是那么慢。 使用-O3时,差异甚至更小:

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

我 将尝试通过两种方式优化此代码

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

  • 估计B中aVec大小的大小,使用resize()重新分配一些空间可能会节省一些时间


  • 您可能应该在bVec上使用大小构造函数,因为它的大小是已知的。 那么对于用向量A填充它的罪魁祸首,你可能 希望在bVec内部的每个avec上使用vector::reserve,根据要提供的数据数量,使用任意大小


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

    该代码不编译
    A=readA(line)
    不是有效语句,并且缺少分号。编译器支持C++11吗?因为这个代码将真正受益于移动语义学。我使用C++ 0x,这不是和C++ 11一样吗?@ NaveN:不,C++ 11是C++以前版本的巨大升级。@ NaveEnSmiARa是的,它们引用的是同一个标准。C++0x源于预期该标准将在2010年之前发布。这是我第一次怀疑,但已证实事实并非如此。我尝试添加了a.x=“AB”;和a.y=“XXXXX YYYY”;对你的readA来说,它不能完全运行。你说不能完全运行是什么意思?通过添加字符串,您会消耗更多的RAM,因此,如果您没有大量的RAM,那么最好在增加向量中记录的大小时减少_的数量。使用a.x=“AB”;和a.y=“XXXXX YYYY”;但_的个数A=5E6;这需要6秒和7秒(-O3)。你是对的!这是idx函数,因为我通过值将bVec传递给它。运行你的代码让我很好奇,并最终解决了这个问题。@NaveenSharma好的,请记住这一点,以后你可能会问任何问题:发布完整的示例。这是有原因的,这里的问题是在你没有发布的代码中…我用-OFASTREFERE编译,没有改进。我将编辑代码以反映我是如何做到这一点的。
    Elapsed test 1:9 s
    Elapsed test 2:7 s