[odb-users] Questions about accessing database in parrallel(PPL library) using odb

Music samal zxbzswxr at gmail.com
Thu Nov 1 07:31:56 EDT 2018


I want to read data from database , and using Microsoft PPL  for parallel
support,

I write an class A, it has an id name which has string type and an Integer
menber

#pragma db object pointer(std::tr1::shared_ptr)
class A
{
public:
A(const string name_):name(name_) {}
~A() {}

friend class odb::access;
A() {}
#pragma db id
string name;

int  number;

};

I just test three scenes
the serial scene,
the parrallel scene using parrallel_for_each from PPL
the parrallel scene using task from PPL
they all do the same thing, persisting 100 objects to database



template <class Function>
__int64 time_call(Function&& f)
{
__int64 begin = GetTickCount();
f();
return GetTickCount() - begin;
}




//  Parrallel test; create
void ParrallelFun(std::vector<int> & vAlist, shared_ptr<database> & db)
{
parallel_for_each(begin(vAlist), end(vAlist), [&](int i)
{
transaction t(db->begin());
string newName = "Parallel_A" + to_string(i);
shared_ptr<A>  tempA(new A(newName));
tempA->number = i;
db->persist(tempA);
// wait(10);
t.commit();
// wait(4);
});
}

//  serialize test
void SerializeFun(std::vector<int> & vAlist , shared_ptr<database> & db)
{

for (auto iter : vAlist)
{
transaction t(db->begin());
string newName = "Serial_A" + to_string(iter);
shared_ptr<A>  tempA(new A(newName));
tempA->number = iter;
db->persist(tempA);
// wait(10);
t.commit();
}

}


//  two task test

void TaskParallel_1();
void TaskParallel_2();



int main(int argc, char* argv[])
{
try
{
//  PPLtest
shared_ptr<database> db(new
odb::pgsql::database("postgres","123456","postgres","localhost",5432));
std::vector<int >  vList(100);
for (int i = 0; i < 100; i++)
{
vList[i] = i;
}
__int64 elapseSerial = time_call([&vList, &db] {

SerializeFun(vList, db);
});

__int64 elapseParallel = time_call([&vList, &db] {
ParrallelFun(vList, db);
});


__int64 elapseParallelTask = time_call([]{
array<task<void>, 2> tasks =
{
create_task([] { TaskParallel_1(); }),
create_task([] { TaskParallel_2(); })
};

auto joinTask = when_all(begin(tasks), end(tasks));

joinTask.wait();
});



cout << "serial time: " << elapseSerial << " ms" << endl;
cout << "parrallel time : " << elapseParallel << " ms" << endl;
cout << "two Task time : " << elapseParallelTask << "ms" << endl;

}
catch (const odb::exception& odberr)
{
cerr << odberr.what() << endl;


}

system("pause");
return 0;
}


void TaskParallel_1()
{
shared_ptr<database> db1(new
odb::pgsql::database("postgres","123456","postgres","localhost",5432));


for (unsigned int i = 0; i < 50; i++)
{
transaction t(db1->begin());
string newName = "TaskParallel_1_" + to_string(i);
shared_ptr<A> temp(new A(newName));
temp->number = i;
db1->persist(temp);
t.commit();
}


}


void TaskParallel_2()
{
shared_ptr<database> db2(new odb::pgsql::database("postgres", "123456",
"postgres", "localhost", 5432));

for (unsigned int i = 0; i < 50; i++)
{
transaction t(db2->begin());
string newName = "TaskParallel_2_" + to_string(i);
shared_ptr<A> temp(new A(newName));
temp->number = i;
db2->persist(temp);
t.commit();

}

}

the ouput is somewhat puzzle to me,
let me list the output here
serial time : 406ms
parrallel time : 2610ms
two Task time: 359ms

  parrallel_for_each  presents   terriblely unacceptable result .Something
must limit its performance. I  tended to  my friends for help , he told  me
may be it's the database connection ,not  transaction that impacts the
parrallel access performance..
so I just tried the third scene, I use two database variable for connection
independently in
task, the performace really improved.
Really is the database connection the main factor impose the parrallel
accessing perfomance?
Can anyone supply more advices about parrallel accessing using odb?

os : windows 10
compiler:vs2017


More information about the odb-users mailing list