]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Move the sqlite3VdbeSerialType() routine in-line in the OP_MakeRecord opcode.
authordrh <drh@noemail.net>
Thu, 11 Jul 2019 19:22:36 +0000 (19:22 +0000)
committerdrh <drh@noemail.net>
Thu, 11 Jul 2019 19:22:36 +0000 (19:22 +0000)
Optimizing compilers were doing this already.  By doing it manually, we can
omit some redundant tests and make the whole thing run a million cycles faster
and use about 80 bytes less code space.

FossilOrigin-Name: d837ab0da52632699abc09320980606aef020df5020c253f99c97e24bf3c6d00

manifest
manifest.uuid
src/vdbe.c
src/vdbeInt.h
src/vdbeaux.c

index fcf4a4f733a117c86117243de8e5146d67105062..7f528c7134009c9f864668725ccbce6326c45c6e 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Version\s3.29.0
-D 2019-07-10T17:32:03.802
+C Move\sthe\ssqlite3VdbeSerialType()\sroutine\sin-line\sin\sthe\sOP_MakeRecord\sopcode.\nOptimizing\scompilers\swere\sdoing\sthis\salready.\s\sBy\sdoing\sit\smanually,\swe\scan\nomit\ssome\sredundant\stests\sand\smake\sthe\swhole\sthing\srun\sa\smillion\scycles\sfaster\nand\suse\sabout\s80\sbytes\sless\scode\sspace.
+D 2019-07-11T19:22:36.389
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -594,11 +594,11 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4
 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507
 F src/util.c aef606a78b85d042138a841babbc0f98471b19b9a340b962e8fae307bc8cf3da
 F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf
-F src/vdbe.c aaa36d1ac7d55baf007e9c03ee7c826834a51dfe7a56ba4c386318695dd87c99
+F src/vdbe.c 6747c7db45059c04b29dbf4ac2d942fc64eb9be630e6b57e5383b14963d54d74
 F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237
-F src/vdbeInt.h 3ba14553508d66f58753952d6dd287dce4ec735de02c6440858b4891aed51c17
+F src/vdbeInt.h 889c52272a02cea8af6e21b493b08bc9a043e3372a77fdfe838d25e73a47ac92
 F src/vdbeapi.c f9161e5c77f512fbb80091ce8af621d19c9556bda5e734cffaac1198407400da
-F src/vdbeaux.c 3a803d75875031309204df90977059b12ffb706d16b4baa5e2d99f4353962582
+F src/vdbeaux.c a2da4e67d337d128ec91b295fbd747bb45b4fd3bed0c658af5d7d3000f202fa5
 F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191
 F src/vdbemem.c f6f277d17d50972571d1394535d4c3d156fdea871d8f327f5b9479984054015a
 F src/vdbesort.c 66592d478dbb46f19aed0b42222325eadb84deb40a90eebe25c6e7c1d8468f47
@@ -1831,10 +1831,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 6f328c35947d6b3a0741514757b8944692203e89bdb2e7f9bbce8ad9288be344
-R 3dc95c8af87e7b557da20a5426ebc03a
-T +bgcolor * #d0c0ff
-T +sym-release *
-T +sym-version-3.29.0 *
+P fc82b73eaac8b36950e527f12c4b5dc1e147e6f4ad2217ae43ad82882a88bfa6
+R e260e19892adbd2f0708577d483baea9
 U drh
-Z 4d356946c4c6edd871b6d6986b095a05
+Z d46113f7ae5239b50bcbe10562e19614
index 0a078bf4dac0c1684d77f3cb93484f9344f523ec..704f2eb637cac2d7d7981a06bc2e7a544399f885 100644 (file)
@@ -1 +1 @@
-fc82b73eaac8b36950e527f12c4b5dc1e147e6f4ad2217ae43ad82882a88bfa6
\ No newline at end of file
+d837ab0da52632699abc09320980606aef020df5020c253f99c97e24bf3c6d00
\ No newline at end of file
index d697d6b1e0d59703ee7c3b1f14f14d6e239ee312..6c34fb0203917f6939ec7dc4e7dea6f4d48f32a5 100644 (file)
@@ -2932,9 +2932,8 @@ case OP_MakeRecord: {
   pRec = pLast;
   do{
     assert( memIsValid(pRec) );
-    serial_type = sqlite3VdbeSerialType(pRec, file_format, &len);
-    if( pRec->flags & MEM_Zero ){
-      if( serial_type==0 ){
+    if( pRec->flags & MEM_Null ){
+      if( pRec->flags & MEM_Zero ){
         /* Values with MEM_Null and MEM_Zero are created by xColumn virtual
         ** table methods that never invoke sqlite3_result_xxxxx() while
         ** computing an unchanging column value in an UPDATE statement.
@@ -2942,19 +2941,78 @@ case OP_MakeRecord: {
         ** so that they can be passed through to xUpdate and have
         ** a true sqlite3_value_nochange(). */
         assert( pOp->p5==OPFLAG_NOCHNG_MAGIC || CORRUPT_DB );
-        serial_type = 10;
-      }else if( nData ){
-        if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem;
+        pRec->uTemp = 10;
       }else{
-        nZero += pRec->u.nZero;
-        len -= pRec->u.nZero;
+        pRec->uTemp = 0;  /* Serial-type 0 means NULL */
       }
+      nHdr++;
+    }else if( pRec->flags & (MEM_Int|MEM_IntReal) ){
+      /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
+      i64 i = pRec->u.i;
+      u64 u;
+      testcase( pRec->flags & MEM_Int );
+      testcase( pRec->flags & MEM_IntReal );
+      if( i<0 ){
+        u = ~i;
+      }else{
+        u = i;
+      }
+      nHdr++;
+      if( u<=127 ){
+        if( (i&1)==i && file_format>=4 ){
+          pRec->uTemp = 8+(u32)u;
+        }else{
+          nData++;
+          pRec->uTemp = 1;
+        }
+      }else if( u<=32767 ){
+        nData += 2;
+        pRec->uTemp = 2;
+      }else if( u<=8388607 ){
+        nData += 3;
+        pRec->uTemp = 3;
+      }else if( u<=2147483647 ){
+        nData += 4;
+        pRec->uTemp = 4;
+      }else if( u<=140737488355327LL ){
+        nData += 6;
+        pRec->uTemp = 5;
+      }else{
+        nData += 8;
+        if( pRec->flags & MEM_IntReal ){
+          /* If the value is IntReal and is going to take up 8 bytes to store
+          ** as an integer, then we might as well make it an 8-byte floating
+          ** point value */
+          pRec->u.r = (double)pRec->u.i;
+          pRec->flags &= ~MEM_IntReal;
+          pRec->flags |= MEM_Real;
+          pRec->uTemp = 7;
+        }else{
+          pRec->uTemp = 6;
+        }
+      }
+    }else if( pRec->flags & MEM_Real ){
+      nHdr++;
+      nData += 8;
+      pRec->uTemp = 7;
+    }else{
+      assert( db->mallocFailed || pRec->flags&(MEM_Str|MEM_Blob) );
+      assert( pRec->n>=0 );
+      len = (u32)pRec->n;
+      serial_type = (len*2) + 12 + ((pRec->flags & MEM_Str)!=0);
+      if( pRec->flags & MEM_Zero ){
+        serial_type += pRec->u.nZero*2;
+        if( nData ){
+          if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem;
+          len += pRec->u.nZero;
+        }else{
+          nZero += pRec->u.nZero;
+        }
+      }
+      nData += len;
+      nHdr += sqlite3VarintLen(serial_type);
+      pRec->uTemp = serial_type;
     }
-    nData += len;
-    testcase( serial_type==127 );
-    testcase( serial_type==128 );
-    nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type);
-    pRec->uTemp = serial_type;
     if( pRec==pData0 ) break;
     pRec--;
   }while(1);
index 17e057b1888918639bf38f4e96cd52366a0148a2..3332b4838f86e155e3213290554679b7c53cb130 100644 (file)
@@ -486,7 +486,9 @@ int sqlite3VdbeCursorMoveto(VdbeCursor**, int*);
 int sqlite3VdbeCursorRestore(VdbeCursor*);
 u32 sqlite3VdbeSerialTypeLen(u32);
 u8 sqlite3VdbeOneByteSerialTypeLen(u8);
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
 u32 sqlite3VdbeSerialType(Mem*, int, u32*);
+#endif
 u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
 u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
 void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int);
index 8dd2b421aa28e9ab3e43012d1a1fc6f3e9691e35..c21d7db40ae3631a48fb7c8dd98fc3c96dfae1f9 100644 (file)
@@ -3430,10 +3430,16 @@ int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){
 ** of SQLite will not understand those serial types.
 */
 
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
 /*
 ** Return the serial-type for the value stored in pMem.
 **
 ** This routine might convert a large MEM_IntReal value into MEM_Real.
+**
+** 2019-07-11:  The primary user of this subroutine was the OP_MakeRecord
+** opcode in the byte-code engine.  But by moving this routine in-line, we
+** can omit some redundant tests and make that opcode a lot faster.  So
+** this routine is now only used by the STAT3/4 logic.
 */
 u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
   int flags = pMem->flags;
@@ -3494,6 +3500,7 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
   *pLen = n;
   return ((n*2) + 12 + ((flags&MEM_Str)!=0));
 }
+#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
 
 /*
 ** The sizes for serial types less than 128