I'm using c++ builder 10.2 tokyo on windows 10 and sqlite 3.23.1. I was working 
on code that stored RowIDs in a vector. I was sizing the vector beforehand and 
then timing how long it took to store the RowIDs returned by an sqlite query. 
By accident I sized the vector too big (by a factor of 10) and found the 
timings doubled (sometimes tripled) despite the fact it was still only stepping 
through the same query. We're talking going from 20 secs to 40-60 secs.

At first I thought 'memory problem' BUT as I'm using a ms surface pro 4 with 16 
GB ram and 512 GB SSD and running a 64 bit release version I thought how can 
that be? I mean the mistakenly sized vector only used 8 GB?

I've managed to whittle the problem down to the following console application. 
The 'Big' table in the following code has just under 112 million records and 
contains 2 integer columns and 4 text columns (full_name_1, 
full_name_2,sort_name_1,sort_name_2). It has one (unique) index on the 2 
integer columns. I did a vacuum on the database beforehand. Apart from 
background tasks the console app was the only one running.

#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#pragma argsused
#include <tchar.h>
#include <stdio.h>
#include <conio.h>
#include <iostream>
#include <vector>
#include "sqlite.h"

std::vector<int64_t> v;
const int Size[]={112000000,1000000000}; // 112 million, 1 billion
int _tmain(int argc, _TCHAR* argv[])
{
        sqlite3 *DB;
        sqlite3_open("c:/SQLiteData/Formbook.db",&DB);
        sqlite3_stmt *stmt;
        sqlite3_prepare_v2(DB,"select RowID from Big order by 
RowID",-1,&stmt,NULL);

        for (int i=0; i<2; i++)
        {
                v.resize(Size[i]);

                // NB the exact same code is executed whether i is 0 or 1. The 
only thing that
                // changes is the size() of v and v isn't even used in the 
timed code below.

                clock_t Start=clock();

                while (sqlite3_step(stmt)==SQLITE_ROW) {}

                // Above just steps through stmt (111,724,900 steps to be 
exact).

                std::cout << 1.0*(clock()-Start)/CLOCKS_PER_SEC << std::endl;

                sqlite3_reset(stmt);
        }
        sqlite3_finalize(stmt);
        sqlite3_close(DB);
        getch();
        return 0;
}

5 sets of timings (secs) were as follows

i==0 i==1
17.610    24.172
20.344    24.594
19.953    24.375
19.891    23.594
19.938    25.516

I can't understand why the second pass (exact same code executed) takes an 
average of 4.8 secs longer.

To add to the puzzle

I tried making v an int64_t*, replaced the resize with v=new int64_t[Size[i]] 
and added delete [] v to the end of the inner block. Pretty much the same thing 
as far as memory goes yet the average timings for i==0 and i==1 were almost 
identical at around 17.4.

I tried replacing the sqlite related code with non-sqlite code e.g. populating 
v up to v.begin+112000000 using rand(). Again the timing anomaly disappeared.

I swapped Size[0] with Size[1] so that the resize was going from large to 
small. The timings on each pass were then similar but were still around the 
24.xxx mark associated with the i==1 pass.

I copied the Big table from its current db to a new db where it was the only 
table. I then redid the timings using the new db but there was no real change.

i==0 i==1
17.594    25.672
20.563    24.406
21.219    23.843
20.484    25.343
20.562    25.172

I lastly tried gradually lowering Size[1] from 1 billion to 200 million step 
200 million. There was little difference to the results for Size[1]=800,000,000 
but at Size[1]=600,000,000 the difference was down to under a second. At 
Size[1]=400,000,000 timings for i==0 and i==1 were pretty much the same.


While that last test suggests it must be a memory issue it begs the question 
why was there no difference in timings for i==0 & i==1 when an array was used 
rather than a vector? Surely the memory requirements are very similar?

The timing anomaly was still apparent when Size[1]=800 million so why, when 
you've got 16 GB ram, does a 6.4 GB vector cause any problems?

What's it got to do with sqlite, if anything? Why was sqlite_step slowed down?

Any suggestions appreciated.
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to