]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Performance optimization in the B-Tree cursor allocator btreeCursor(), making
authordrh <>
Fri, 3 Dec 2021 13:42:41 +0000 (13:42 +0000)
committerdrh <>
Fri, 3 Dec 2021 13:42:41 +0000 (13:42 +0000)
it about 800K CPU cycles faster in speedtest1, and reducing the executable
size by about 100 bytes.

FossilOrigin-Name: 9df939716ace8cfe60340bbe83fc52d452ea40c29c856c588f9a1b8973282391

manifest
manifest.uuid
src/btree.c

index 65ea3a6c49abd45010d3776129a7c62d01ecd74c..18e751c5d30aa1af1a536f5bf0689765a390f7c2 100644 (file)
--- 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
index a9c01fe47e1981dec04d7609124cdbbb35e42137..380663b6d67cc1b8288da09c70158b8541eea720 100644 (file)
@@ -1 +1 @@
-1f2252e65dc5847c82246fab87dcad035bf594ba7c45362de87a009b7ebcf2d6
\ No newline at end of file
+9df939716ace8cfe60340bbe83fc52d452ea40c29c856c588f9a1b8973282391
\ No newline at end of file
index ba35af03f01bf7139bdebe05c9d25a4d9ce55286..7dfce901ab8a3fbafa1479df51b71b59876c87cc 100644 (file)
@@ -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(