1
0
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:
drh
2016-05-20 14:54:54 +00:00
parent 1524c672e9
commit b982bfea37
5 changed files with 55 additions and 47 deletions

View File

@@ -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. 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:11:37.786 D 2016-05-20T14:54:54.663
F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7
@@ -368,7 +368,7 @@ F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
F src/pager.c 3910579bfbe323dfabed2b95d201159b61b8ef42 F src/pager.c 3910579bfbe323dfabed2b95d201159b61b8ef42
F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681
F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e
F src/pcache.c f398c0084399e7481482cbc6a578a3cc4c3675f3 F src/pcache.c 50fb5728dbfb92461f89f8763ff8b60d0dbeba2c
F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490
F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d
F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84 F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84
@@ -377,7 +377,7 @@ F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e
F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598
F src/rowset.c 49eb91c588a2bab36647368e031dc5b66928149d F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
F src/select.c a0c4abf54bc6bd3a9c77a36ef3d1676045706cb2 F src/select.c a0c4abf54bc6bd3a9c77a36ef3d1676045706cb2
F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6
F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54 F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54
@@ -451,7 +451,7 @@ F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c
F src/vdbeaux.c ace1875da40b7185e604586768d5ac90de7e4f7f F src/vdbeaux.c ace1875da40b7185e604586768d5ac90de7e4f7f
F src/vdbeblob.c c9f2f494b911c6fa34efd9803f0a10807da80f77 F src/vdbeblob.c c9f2f494b911c6fa34efd9803f0a10807da80f77
F src/vdbemem.c 5cfef60e60e19cab6275d1b975bf4c791d575beb F src/vdbemem.c 5cfef60e60e19cab6275d1b975bf4c791d575beb
F src/vdbesort.c 0a8f98366ae794442e6d1ef71d9553226d885d19 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c
F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484 F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484
F src/vtab.c 23b6cdfa996152d43b390504ed4a942c8caf3a00 F src/vtab.c 23b6cdfa996152d43b390504ed4a942c8caf3a00
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
@@ -1490,8 +1490,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 645bd696dfd86d8c93080f6ebfddbc9639ec088b ed1b30dc932a7c03e173b130c5f55f9989c7e0b4 P 559733b09e9630fac9d9318a7ecbaba9134e9160
R b166646a4114a46c17faadb7ecf63948 R db641f928488147ea4b353a0a8e4e73d
T +closed ed1b30dc932a7c03e173b130c5f55f9989c7e0b4
U drh U drh
Z aa696592564772ea00c367935ddfa343 Z 8f08ede060795a413d5c246d730b7a0d

View File

@@ -1 +1 @@
559733b09e9630fac9d9318a7ecbaba9134e9160 9033afbb31b28a8ad6856ac1f773d8e83bc9ec1c

View File

@@ -692,23 +692,25 @@ void sqlite3PcacheClear(PCache *pCache){
static PgHdr *pcacheMergeDirtyList(PgHdr *pA, PgHdr *pB){ static PgHdr *pcacheMergeDirtyList(PgHdr *pA, PgHdr *pB){
PgHdr result, *pTail; PgHdr result, *pTail;
pTail = &result; pTail = &result;
while( pA && pB ){ assert( pA!=0 && pB!=0 );
for(;;){
if( pA->pgno<pB->pgno ){ if( pA->pgno<pB->pgno ){
pTail->pDirty = pA; pTail->pDirty = pA;
pTail = pA; pTail = pA;
pA = pA->pDirty; pA = pA->pDirty;
if( pA==0 ){
pTail->pDirty = pB;
break;
}
}else{ }else{
pTail->pDirty = pB; pTail->pDirty = pB;
pTail = pB; pTail = pB;
pB = pB->pDirty; pB = pB->pDirty;
} if( pB==0 ){
}
if( pA ){
pTail->pDirty = pA; pTail->pDirty = pA;
}else if( pB ){ break;
pTail->pDirty = pB; }
}else{ }
pTail->pDirty = 0;
} }
return result.pDirty; return result.pDirty;
} }
@@ -750,7 +752,8 @@ static PgHdr *pcacheSortDirtyList(PgHdr *pIn){
} }
p = a[0]; p = a[0];
for(i=1; i<N_SORT_BUCKET; i++){ 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; return p;
} }

View File

@@ -242,27 +242,25 @@ static struct RowSetEntry *rowSetEntryMerge(
struct RowSetEntry *pTail; struct RowSetEntry *pTail;
pTail = &head; pTail = &head;
while( pA && pB ){ assert( pA!=0 && pB!=0 );
for(;;){
assert( pA->pRight==0 || pA->v<=pA->pRight->v ); assert( pA->pRight==0 || pA->v<=pA->pRight->v );
assert( pB->pRight==0 || pB->v<=pB->pRight->v ); assert( pB->pRight==0 || pB->v<=pB->pRight->v );
if( pA->v<pB->v ){ if( pA->v<=pB->v ){
pTail->pRight = pA; if( pA->v<pB->v ) pTail = pTail->pRight = pA;
pA = pA->pRight; pA = pA->pRight;
pTail = pTail->pRight; if( pA==0 ){
}else if( pB->v<pA->v ){
pTail->pRight = pB; pTail->pRight = pB;
break;
}
}else{
pTail = pTail->pRight = pB;
pB = pB->pRight; pB = pB->pRight;
pTail = pTail->pRight; if( pB==0 ){
}else{
pA = pA->pRight;
}
}
if( pA ){
assert( pA->pRight==0 || pA->v<=pA->pRight->v );
pTail->pRight = pA; pTail->pRight = pA;
}else{ break;
assert( pB==0 || pB->pRight==0 || pB->v<=pB->pRight->v ); }
pTail->pRight = pB; }
} }
return head.pRight; return head.pRight;
} }
@@ -286,9 +284,10 @@ static struct RowSetEntry *rowSetEntrySort(struct RowSetEntry *pIn){
aBucket[i] = pIn; aBucket[i] = pIn;
pIn = pNext; pIn = pNext;
} }
pIn = 0; pIn = aBucket[0];
for(i=0; i<sizeof(aBucket)/sizeof(aBucket[0]); i++){ for(i=1; i<sizeof(aBucket)/sizeof(aBucket[0]); i++){
pIn = rowSetEntryMerge(pIn, aBucket[i]); if( aBucket[i]==0 ) continue;
pIn = pIn ? rowSetEntryMerge(pIn, aBucket[i]) : aBucket[i];
} }
return pIn; return pIn;
} }

View File

@@ -1342,19 +1342,18 @@ static int vdbeSortAllocUnpacked(SortSubtask *pTask){
/* /*
** Merge the two sorted lists p1 and p2 into a single list. ** 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 */ SortSubtask *pTask, /* Calling thread context */
SorterRecord *p1, /* First list to merge */ SorterRecord *p1, /* First list to merge */
SorterRecord *p2, /* Second list to merge */ SorterRecord *p2 /* Second list to merge */
SorterRecord **ppOut /* OUT: Head of merged list */
){ ){
SorterRecord *pFinal = 0; SorterRecord *pFinal = 0;
SorterRecord **pp = &pFinal; SorterRecord **pp = &pFinal;
int bCached = 0; int bCached = 0;
while( p1 && p2 ){ assert( p1!=0 && p2!=0 );
for(;;){
int res; int res;
res = pTask->xCompare( res = pTask->xCompare(
pTask, &bCached, SRVAL(p1), p1->nVal, SRVAL(p2), p2->nVal pTask, &bCached, SRVAL(p1), p1->nVal, SRVAL(p2), p2->nVal
@@ -1364,15 +1363,22 @@ static void vdbeSorterMerge(
*pp = p1; *pp = p1;
pp = &p1->u.pNext; pp = &p1->u.pNext;
p1 = p1->u.pNext; p1 = p1->u.pNext;
if( p1==0 ){
*pp = p2;
break;
}
}else{ }else{
*pp = p2; *pp = p2;
pp = &p2->u.pNext; pp = &p2->u.pNext;
p2 = p2->u.pNext; p2 = p2->u.pNext;
bCached = 0; 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; p->u.pNext = 0;
for(i=0; aSlot[i]; i++){ for(i=0; aSlot[i]; i++){
vdbeSorterMerge(pTask, p, aSlot[i], &p); p = vdbeSorterMerge(pTask, p, aSlot[i]);
aSlot[i] = 0; aSlot[i] = 0;
} }
aSlot[i] = p; aSlot[i] = p;
@@ -1434,7 +1440,8 @@ static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){
p = 0; p = 0;
for(i=0; i<64; i++){ 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; pList->pList = p;