mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-14 00:22:38 +03:00
Optimizations to link list merge sort code in vdbesort.c, pcache.c, and
rowset.c. Resulting binaries are 10 bytes smaller and use 0.03% fewer CPU cycles. FossilOrigin-Name: 9033afbb31b28a8ad6856ac1f773d8e83bc9ec1c
This commit is contained in:
17
manifest
17
manifest
@@ -1,5 +1,5 @@
|
||||
C For\squeries\swith\sboth\sORDER\sBY\sand\sLIMIT,\sif\sthe\srows\sof\sthe\sinner\sloop\sare\nemitted\sin\sORDER\sBY\sorder\sand\sthe\sLIMIT\shas\sbeen\sreached,\sthen\soptimize\sby\nexiting\sthe\sinner\sloop\sand\scontinuing\swith\sthe\snext\scycle\sof\sthe\sfirst\souter\nloop.
|
||||
D 2016-05-20T14:11:37.786
|
||||
C Optimizations\sto\slink\slist\smerge\ssort\scode\sin\svdbesort.c,\spcache.c,\sand\nrowset.c.\s\sResulting\sbinaries\sare\s10\sbytes\ssmaller\sand\suse\s0.03%\sfewer\sCPU\ncycles.
|
||||
D 2016-05-20T14:54:54.663
|
||||
F Makefile.in f59e0763ff448719fc1bd25513882b0567286317
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7
|
||||
@@ -368,7 +368,7 @@ F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
||||
F src/pager.c 3910579bfbe323dfabed2b95d201159b61b8ef42
|
||||
F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681
|
||||
F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e
|
||||
F src/pcache.c f398c0084399e7481482cbc6a578a3cc4c3675f3
|
||||
F src/pcache.c 50fb5728dbfb92461f89f8763ff8b60d0dbeba2c
|
||||
F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490
|
||||
F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d
|
||||
F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84
|
||||
@@ -377,7 +377,7 @@ F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e
|
||||
F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1
|
||||
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||
F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598
|
||||
F src/rowset.c 49eb91c588a2bab36647368e031dc5b66928149d
|
||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||
F src/select.c a0c4abf54bc6bd3a9c77a36ef3d1676045706cb2
|
||||
F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6
|
||||
F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54
|
||||
@@ -451,7 +451,7 @@ F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c
|
||||
F src/vdbeaux.c ace1875da40b7185e604586768d5ac90de7e4f7f
|
||||
F src/vdbeblob.c c9f2f494b911c6fa34efd9803f0a10807da80f77
|
||||
F src/vdbemem.c 5cfef60e60e19cab6275d1b975bf4c791d575beb
|
||||
F src/vdbesort.c 0a8f98366ae794442e6d1ef71d9553226d885d19
|
||||
F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c
|
||||
F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484
|
||||
F src/vtab.c 23b6cdfa996152d43b390504ed4a942c8caf3a00
|
||||
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
@@ -1490,8 +1490,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 645bd696dfd86d8c93080f6ebfddbc9639ec088b ed1b30dc932a7c03e173b130c5f55f9989c7e0b4
|
||||
R b166646a4114a46c17faadb7ecf63948
|
||||
T +closed ed1b30dc932a7c03e173b130c5f55f9989c7e0b4
|
||||
P 559733b09e9630fac9d9318a7ecbaba9134e9160
|
||||
R db641f928488147ea4b353a0a8e4e73d
|
||||
U drh
|
||||
Z aa696592564772ea00c367935ddfa343
|
||||
Z 8f08ede060795a413d5c246d730b7a0d
|
||||
|
||||
@@ -1 +1 @@
|
||||
559733b09e9630fac9d9318a7ecbaba9134e9160
|
||||
9033afbb31b28a8ad6856ac1f773d8e83bc9ec1c
|
||||
21
src/pcache.c
21
src/pcache.c
@@ -692,23 +692,25 @@ void sqlite3PcacheClear(PCache *pCache){
|
||||
static PgHdr *pcacheMergeDirtyList(PgHdr *pA, PgHdr *pB){
|
||||
PgHdr result, *pTail;
|
||||
pTail = &result;
|
||||
while( pA && pB ){
|
||||
assert( pA!=0 && pB!=0 );
|
||||
for(;;){
|
||||
if( pA->pgno<pB->pgno ){
|
||||
pTail->pDirty = pA;
|
||||
pTail = pA;
|
||||
pA = pA->pDirty;
|
||||
if( pA==0 ){
|
||||
pTail->pDirty = pB;
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
pTail->pDirty = pB;
|
||||
pTail = pB;
|
||||
pB = pB->pDirty;
|
||||
}
|
||||
}
|
||||
if( pA ){
|
||||
if( pB==0 ){
|
||||
pTail->pDirty = pA;
|
||||
}else if( pB ){
|
||||
pTail->pDirty = pB;
|
||||
}else{
|
||||
pTail->pDirty = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.pDirty;
|
||||
}
|
||||
@@ -750,7 +752,8 @@ static PgHdr *pcacheSortDirtyList(PgHdr *pIn){
|
||||
}
|
||||
p = a[0];
|
||||
for(i=1; i<N_SORT_BUCKET; i++){
|
||||
p = pcacheMergeDirtyList(p, a[i]);
|
||||
if( a[i]==0 ) continue;
|
||||
p = p ? pcacheMergeDirtyList(p, a[i]) : a[i];
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
35
src/rowset.c
35
src/rowset.c
@@ -242,27 +242,25 @@ static struct RowSetEntry *rowSetEntryMerge(
|
||||
struct RowSetEntry *pTail;
|
||||
|
||||
pTail = &head;
|
||||
while( pA && pB ){
|
||||
assert( pA!=0 && pB!=0 );
|
||||
for(;;){
|
||||
assert( pA->pRight==0 || pA->v<=pA->pRight->v );
|
||||
assert( pB->pRight==0 || pB->v<=pB->pRight->v );
|
||||
if( pA->v<pB->v ){
|
||||
pTail->pRight = pA;
|
||||
if( pA->v<=pB->v ){
|
||||
if( pA->v<pB->v ) pTail = pTail->pRight = pA;
|
||||
pA = pA->pRight;
|
||||
pTail = pTail->pRight;
|
||||
}else if( pB->v<pA->v ){
|
||||
if( pA==0 ){
|
||||
pTail->pRight = pB;
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
pTail = pTail->pRight = pB;
|
||||
pB = pB->pRight;
|
||||
pTail = pTail->pRight;
|
||||
}else{
|
||||
pA = pA->pRight;
|
||||
}
|
||||
}
|
||||
if( pA ){
|
||||
assert( pA->pRight==0 || pA->v<=pA->pRight->v );
|
||||
if( pB==0 ){
|
||||
pTail->pRight = pA;
|
||||
}else{
|
||||
assert( pB==0 || pB->pRight==0 || pB->v<=pB->pRight->v );
|
||||
pTail->pRight = pB;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return head.pRight;
|
||||
}
|
||||
@@ -286,9 +284,10 @@ static struct RowSetEntry *rowSetEntrySort(struct RowSetEntry *pIn){
|
||||
aBucket[i] = pIn;
|
||||
pIn = pNext;
|
||||
}
|
||||
pIn = 0;
|
||||
for(i=0; i<sizeof(aBucket)/sizeof(aBucket[0]); i++){
|
||||
pIn = rowSetEntryMerge(pIn, aBucket[i]);
|
||||
pIn = aBucket[0];
|
||||
for(i=1; i<sizeof(aBucket)/sizeof(aBucket[0]); i++){
|
||||
if( aBucket[i]==0 ) continue;
|
||||
pIn = pIn ? rowSetEntryMerge(pIn, aBucket[i]) : aBucket[i];
|
||||
}
|
||||
return pIn;
|
||||
}
|
||||
|
||||
@@ -1342,19 +1342,18 @@ static int vdbeSortAllocUnpacked(SortSubtask *pTask){
|
||||
|
||||
/*
|
||||
** Merge the two sorted lists p1 and p2 into a single list.
|
||||
** Set *ppOut to the head of the new list.
|
||||
*/
|
||||
static void vdbeSorterMerge(
|
||||
static SorterRecord *vdbeSorterMerge(
|
||||
SortSubtask *pTask, /* Calling thread context */
|
||||
SorterRecord *p1, /* First list to merge */
|
||||
SorterRecord *p2, /* Second list to merge */
|
||||
SorterRecord **ppOut /* OUT: Head of merged list */
|
||||
SorterRecord *p2 /* Second list to merge */
|
||||
){
|
||||
SorterRecord *pFinal = 0;
|
||||
SorterRecord **pp = &pFinal;
|
||||
int bCached = 0;
|
||||
|
||||
while( p1 && p2 ){
|
||||
assert( p1!=0 && p2!=0 );
|
||||
for(;;){
|
||||
int res;
|
||||
res = pTask->xCompare(
|
||||
pTask, &bCached, SRVAL(p1), p1->nVal, SRVAL(p2), p2->nVal
|
||||
@@ -1364,15 +1363,22 @@ static void vdbeSorterMerge(
|
||||
*pp = p1;
|
||||
pp = &p1->u.pNext;
|
||||
p1 = p1->u.pNext;
|
||||
if( p1==0 ){
|
||||
*pp = p2;
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
*pp = p2;
|
||||
pp = &p2->u.pNext;
|
||||
p2 = p2->u.pNext;
|
||||
bCached = 0;
|
||||
if( p2==0 ){
|
||||
*pp = p1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*pp = p1 ? p1 : p2;
|
||||
*ppOut = pFinal;
|
||||
}
|
||||
return pFinal;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1425,7 +1431,7 @@ static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){
|
||||
|
||||
p->u.pNext = 0;
|
||||
for(i=0; aSlot[i]; i++){
|
||||
vdbeSorterMerge(pTask, p, aSlot[i], &p);
|
||||
p = vdbeSorterMerge(pTask, p, aSlot[i]);
|
||||
aSlot[i] = 0;
|
||||
}
|
||||
aSlot[i] = p;
|
||||
@@ -1434,7 +1440,8 @@ static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){
|
||||
|
||||
p = 0;
|
||||
for(i=0; i<64; i++){
|
||||
vdbeSorterMerge(pTask, p, aSlot[i], &p);
|
||||
if( aSlot[i]==0 ) continue;
|
||||
p = p ? vdbeSorterMerge(pTask, p, aSlot[i]) : aSlot[i];
|
||||
}
|
||||
pList->pList = p;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user