我在代码中使用了几个结构。第一个结构是在从一行文本文件中读取数据后构造的,第二个结构包含一个第一类结构的向量。
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秒。 有没有办法保持上述一般结构而不会失去性能。 有效实现这个的任何方法吗?
答案 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)
我会尝试以两种方式优化此代码
定义vector<A*> aVec
而不是vector<A> aVec
,以避免复制构造函数调用,因为您使用的是C ++ 0x
估计B中aVec大小的大小,使用resize()重新设置一些空间可能会节省一些时间
答案 2 :(得分:0)
你应该在bVec上使用大小构造函数,因为它的大小是已知的。 然后,你可能是用A矢量填充它的主要罪魁祸首 想在bVec中的每个avec上使用vector :: reserve,具有任意大小,具体取决于你要输入的数据量。
另外,你确定用-O3编译吗?