From: drh <> Date: Fri, 3 Dec 2021 13:42:41 +0000 (+0000) Subject: Performance optimization in the B-Tree cursor allocator btreeCursor(), making X-Git-Tag: version-3.38.0~201 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2f0bc1d41b0956c75822332dc1af1c680291071a;p=thirdparty%2Fsqlite.git Performance optimization in the B-Tree cursor allocator btreeCursor(), making it about 800K CPU cycles faster in speedtest1, and reducing the executable size by about 100 bytes. FossilOrigin-Name: 9df939716ace8cfe60340bbe83fc52d452ea40c29c856c588f9a1b8973282391 --- diff --git a/manifest b/manifest index 65ea3a6c49..18e751c5d3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Optimizations\sto\sexprAnalyze()\sand\ssqlite3WhereExprUsage()\ssave\sabout\s1.5\nmillion\sCPU\scycles\sfor\sspeedtest1,\sand\sresult\sin\sa\ssmaller\sbinary. -D 2021-12-02T18:15:16.866 +C Performance\soptimization\sin\sthe\sB-Tree\scursor\sallocator\sbtreeCursor(),\smaking\nit\sabout\s800K\sCPU\scycles\sfaster\sin\sspeedtest1,\sand\sreducing\sthe\sexecutable\nsize\sby\sabout\s100\sbytes. +D 2021-12-03T13:42:41.900 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -491,7 +491,7 @@ F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 7c849aac407230278445cb069bebc5f89bf2ddd87c5ed9459b070a9175707b3d F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 13b965a0f3cd57221e3b4e61e24452ec264a5b163de347b03b5039ddcd95cd54 +F src/btree.c be33f2b299c2d1dcdd6c033368731b81c13c2dbc72fe15af64a43871f6cdb437 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h ee9348c4cb9077243b049edc93a82c1f32ca48baeabf2140d41362b9f9139ff7 F src/build.c 179b11b07484497052096d88b953b9a6c22cbb0c23ba75c4347e9a99dae4a6c0 @@ -1933,7 +1933,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 8832fa9088414a8d285a457a4effad0b7d610a87ca73cfb5c5812e784649761e -R 7228b3364cf2efa906def2eee014e4fe +P 1f2252e65dc5847c82246fab87dcad035bf594ba7c45362de87a009b7ebcf2d6 +R 8e0c1c78e15dfcc0933f0a89f97b367f U drh -Z 0ddb7e6cff00de145e1d39d556b5aab6 +Z 5947065c8f3472b5a2f6d47907db0ceb diff --git a/manifest.uuid b/manifest.uuid index a9c01fe47e..380663b6d6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1f2252e65dc5847c82246fab87dcad035bf594ba7c45362de87a009b7ebcf2d6 \ No newline at end of file +9df939716ace8cfe60340bbe83fc52d452ea40c29c856c588f9a1b8973282391 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index ba35af03f0..7dfce901ab 100644 --- a/src/btree.c +++ b/src/btree.c @@ -2693,30 +2693,40 @@ static int removeFromSharingList(BtShared *pBt){ ** MX_CELL_SIZE(pBt) bytes with a 4-byte prefix for a left-child ** pointer. */ -static void allocateTempSpace(BtShared *pBt){ - if( !pBt->pTmpSpace ){ - pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize ); - - /* One of the uses of pBt->pTmpSpace is to format cells before - ** inserting them into a leaf page (function fillInCell()). If - ** a cell is less than 4 bytes in size, it is rounded up to 4 bytes - ** by the various routines that manipulate binary cells. Which - ** can mean that fillInCell() only initializes the first 2 or 3 - ** bytes of pTmpSpace, but that the first 4 bytes are copied from - ** it into a database page. This is not actually a problem, but it - ** does cause a valgrind error when the 1 or 2 bytes of unitialized - ** data is passed to system call write(). So to avoid this error, - ** zero the first 4 bytes of temp space here. - ** - ** Also: Provide four bytes of initialized space before the - ** beginning of pTmpSpace as an area available to prepend the - ** left-child pointer to the beginning of a cell. - */ - if( pBt->pTmpSpace ){ - memset(pBt->pTmpSpace, 0, 8); - pBt->pTmpSpace += 4; - } +static SQLITE_NOINLINE int allocateTempSpace(BtShared *pBt){ + assert( pBt!=0 ); + assert( pBt->pTmpSpace==0 ); + /* This routine is called only by btreeCursor() when allocating the + ** first write cursor for the BtShared object */ + assert( pBt->pCursor!=0 && (pBt->pCursor->curFlags & BTCF_WriteFlag)!=0 ); + pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize ); + if( pBt->pTmpSpace==0 ){ + BtCursor *pCur = pBt->pCursor; + pBt->pCursor = pCur->pNext; /* Unlink the cursor */ + memset(pCur, 0, sizeof(*pCur)); + return SQLITE_NOMEM_BKPT; + } + + /* One of the uses of pBt->pTmpSpace is to format cells before + ** inserting them into a leaf page (function fillInCell()). If + ** a cell is less than 4 bytes in size, it is rounded up to 4 bytes + ** by the various routines that manipulate binary cells. Which + ** can mean that fillInCell() only initializes the first 2 or 3 + ** bytes of pTmpSpace, but that the first 4 bytes are copied from + ** it into a database page. This is not actually a problem, but it + ** does cause a valgrind error when the 1 or 2 bytes of unitialized + ** data is passed to system call write(). So to avoid this error, + ** zero the first 4 bytes of temp space here. + ** + ** Also: Provide four bytes of initialized space before the + ** beginning of pTmpSpace as an area available to prepend the + ** left-child pointer to the beginning of a cell. + */ + if( pBt->pTmpSpace ){ + memset(pBt->pTmpSpace, 0, 8); + pBt->pTmpSpace += 4; } + return SQLITE_OK; } /* @@ -4457,10 +4467,6 @@ static int btreeCursor( assert( pBt->pPage1 && pBt->pPage1->aData ); assert( wrFlag==0 || (pBt->btsFlags & BTS_READ_ONLY)==0 ); - if( wrFlag ){ - allocateTempSpace(pBt); - if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM_BKPT; - } if( iTable<=1 ){ if( iTable<1 ){ return SQLITE_CORRUPT_BKPT; @@ -4477,19 +4483,25 @@ static int btreeCursor( pCur->pKeyInfo = pKeyInfo; pCur->pBtree = p; pCur->pBt = pBt; - pCur->curFlags = wrFlag ? BTCF_WriteFlag : 0; - pCur->curPagerFlags = wrFlag ? 0 : PAGER_GET_READONLY; + pCur->curFlags = 0; /* If there are two or more cursors on the same btree, then all such ** cursors *must* have the BTCF_Multiple flag set. */ for(pX=pBt->pCursor; pX; pX=pX->pNext){ if( pX->pgnoRoot==iTable ){ pX->curFlags |= BTCF_Multiple; - pCur->curFlags |= BTCF_Multiple; + pCur->curFlags = BTCF_Multiple; } } + pCur->eState = CURSOR_INVALID; pCur->pNext = pBt->pCursor; pBt->pCursor = pCur; - pCur->eState = CURSOR_INVALID; + if( wrFlag ){ + pCur->curFlags |= BTCF_WriteFlag; + pCur->curPagerFlags = 0; + if( pBt->pTmpSpace==0 ) return allocateTempSpace(pBt); + }else{ + pCur->curPagerFlags = PAGER_GET_READONLY; + } return SQLITE_OK; } static int btreeCursorWithLock(