1 message in com.mysql.lists.plusplusmore on Result/Row efficiency; patch ...
FromSent OnAttachments
John Hunter07 Aug 2001 12:09.diff
Subject:more on Result/Row efficiency; patch included
From:John Hunter (jdhu@ace.bsd.uchicago.edu)
Date:08/07/2001 12:09:08 PM
List:com.mysql.lists.plusplus
Attachments:

In an earlier post I asked about the inefficiency using

Result res = query.store(); Row row; const Result::const_iterator ie( res.end() ); for (Result::iterator ib = res.begin(); ib != ie; ++ib) { row = *ib; file://this line is SLOW! file://do something with the result }

and Andrius suggested cout << (*ib)[0] << (*ib)[1] << (*ib)[2] /* ... */; which did indeed speed up my code dramatically. I did some profiling today and found that about 33% of the total execution time of my code was spent dereferencing theq Result iterator, even with Andrius improvement. I found that I could get a big savings over the repeated dereferencing with for (Result::const_iterator ib( res.begin() ); ib != ie; ++ib) { const Row& thisRow( *ib ); cout << thisRow[0] << thisRow[1] << thisRow[2] /* ... */; } It turns out this dereferencing is an expensive operation and should be done only once. Even after this fix, 17% of my execution time is devoted to that function (and my code is doing a lot of other stuff!). The deference causes this chain of events, with the total amount of code execution time to the left and the gprof id to the right 0.57 ::operator*(void) [4] 0.57 MysqlRes::operator[](unsigned int) const [5] 0.55 MysqlRes::fetch_row(void) const [3] 0.51 MysqlRow::MysqlRow(char **, MysqlResUse const *, unsigned int *, bool) [6] 0.20 vector<string>::insert [9] 0.15 vector<bool>::insert [12] 0.03 vector<string>::clear [20] Almost all of the time spent on operator()* is in the MysqlRow constructor, and most of that calling the insert() and clear() vector functions. Each of the inserts (for the string and bool) is called for each field. Since the number of fields is known at construction, the vectors can be sized in the variable initialization list and the vector operator()[] can be used instead of insert. This also obviates the need for clear. After these changes are made in the constructor, the average call time for the constructor is reduced from 8.84 to 5.04 micro seconds, a 43% gain in efficiency. Since this function will be called *a lot* for large datasets, the savings can be substantial. Also, I commented out the destructor (which needlessly calls clear for both vectors). This change alone increased the execution time of my code by 6%. So, in summary, with the changes to the mysql suggested and dereferencing the Result iterator halved the execution time of my code. I love gprof. Comments welcome, John Hunter Changes made against version 1.7.9. Here is the diff to sqlplusint/row1.hh # diff row1.hh row1.hh.default > row1.diff