]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Cache the most recently sqlite3_context used by OP_Function and reuse it on function-ctx-cache
authordrh <drh@noemail.net>
Fri, 26 Jun 2015 13:31:02 +0000 (13:31 +0000)
committerdrh <drh@noemail.net>
Fri, 26 Jun 2015 13:31:02 +0000 (13:31 +0000)
subsequent calls, if appropriate. This gives a noticable performance boost.

FossilOrigin-Name: 2f31bdd1b2186659f57a705ecf0eaf590471c374

manifest
manifest.uuid
src/vdbe.c

index a04cf6695bc43df18896ddb728d05025d350ea13..c407a585a3a40847922dbe5e5406a16313e1f814 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Simplify\sthe\spcache\sby\snot\skeeping\scontinuous\strack\sof\spage\s1\sbut\sinstead\njust\sloading\spage\s1\son\sthe\srare\soccasions\swhen\sit\sis\sactually\sneeded.
-D 2015-06-26T02:41:31.913
+C Cache\sthe\smost\srecently\ssqlite3_context\sused\sby\sOP_Function\sand\sreuse\sit\son\nsubsequent\scalls,\sif\sappropriate.\sThis\sgives\sa\snoticable\sperformance\sboost.
+D 2015-06-26T13:31:02.230
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 1063c58075b7400d93326b0eb332b48a54f53025
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -313,7 +313,7 @@ F src/update.c 487747b328b7216bb7f6af0695d6937d5c9e605f
 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
 F src/util.c a6431c92803b975b7322724a7b433e538d243539
 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
-F src/vdbe.c 3af2d06e2b36012631dc3331957df52febdf8678
+F src/vdbe.c 592957316d7bced599384e7897f6ee7728af5a61
 F src/vdbe.h 90048aea1910f9df93e6044592bd4a466dc9c5e7
 F src/vdbeInt.h 20295e482121d13437f69985f77db211cdc8bac1
 F src/vdbeapi.c 6a0d7757987018ff6b1b81bc5293219cd26bb299
@@ -1286,7 +1286,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 8d79f3a1443391bee204bb8c49240f44477168db
-R c56e8779f6e8f4f9de88fc3a0bf56b01
+P 015302f15e46a087ec92f3644c6741600dbf4306
+R 7832174f14c22d1eacdad67bafdfeaa7
+T *branch * function-ctx-cache
+T *sym-function-ctx-cache *
+T -sym-trunk *
 U drh
-Z 87d94359f0bb80945f07f56dd11de5b2
+Z e48fb4a345ac7f54e42bdc087583de4b
index fa2d20be1d2ec72a8c35be562010223ddbf00e2a..e7e93bcbeff44917c4c5cd45a339a0106d122627 100644 (file)
@@ -1 +1 @@
-015302f15e46a087ec92f3644c6741600dbf4306
\ No newline at end of file
+2f31bdd1b2186659f57a705ecf0eaf590471c374
\ No newline at end of file
index 4fd19327eda386d68df2e1c0dd575837a51f5376..5f9d09a7f50396616a9c5ffec4470889c72c9f0c 100644 (file)
@@ -562,6 +562,9 @@ int sqlite3VdbeExec(
 #ifdef VDBE_PROFILE
   u64 start;                 /* CPU clock count at start of opcode */
 #endif
+  Op *pCtxOp = 0;            /* Opcode for which ctx is initialized */
+  sqlite3_context ctx;       /* Function call context */
+
   /*** INSERT STACK UNION HERE ***/
 
   assert( p->magic==VDBE_MAGIC_RUN );  /* sqlite3_step() verifies this */
@@ -943,6 +946,7 @@ case OP_Halt: {
     aOp = p->aOp;
     aMem = p->aMem;
     pOp = &aOp[pcx];
+    pCtxOp = 0;
     break;
   }
   p->rc = pOp->p1;
@@ -1566,35 +1570,39 @@ case OP_CollSeq: {
 case OP_Function: {
   int i;
   Mem *pArg;
-  sqlite3_context ctx;
   sqlite3_value **apVal;
   int n;
 
   n = pOp->p5;
-  apVal = p->apArg;
-  assert( apVal || n==0 );
-  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
-  ctx.pOut = &aMem[pOp->p3];
-  memAboutToChange(p, ctx.pOut);
-
-  assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) );
-  assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
-  pArg = &aMem[pOp->p2];
-  for(i=0; i<n; i++, pArg++){
-    assert( memIsValid(pArg) );
-    apVal[i] = pArg;
-    Deephemeralize(pArg);
-    REGISTER_TRACE(pOp->p2+i, pArg);
+  if( pOp!=pCtxOp ){
+    apVal = p->apArg;
+    assert( apVal || n==0 );
+    assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
+    ctx.pOut = &aMem[pOp->p3];
+
+    assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) );
+    assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
+    pArg = &aMem[pOp->p2];
+    for(i=0; i<n; i++, pArg++){
+      apVal[i] = pArg;
+    }
+    assert( pOp->p4type==P4_FUNCDEF );
+    ctx.pFunc = pOp->p4.pFunc;
+    ctx.iOp = (int)(pOp - aOp);
+    ctx.pVdbe = p;
+    pCtxOp = pOp;
   }
-
-  assert( pOp->p4type==P4_FUNCDEF );
-  ctx.pFunc = pOp->p4.pFunc;
-  ctx.iOp = (int)(pOp - aOp);
-  ctx.pVdbe = p;
+#ifdef SQLITE_DEBUG
+  for(i=0; i<n; i++){
+    assert( memIsValid(p->apArg[i]) );
+    REGISTER_TRACE(pOp->p2+i, p->apArg[i]);
+  }
+#endif
+  memAboutToChange(p, ctx.pOut);
   MemSetTypeFlag(ctx.pOut, MEM_Null);
   ctx.fErrorOrAux = 0;
   db->lastRowid = lastRowid;
-  (*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */
+  (*ctx.pFunc->xFunc)(&ctx, n, p->apArg); /* IMP: R-24505-23230 */
   lastRowid = db->lastRowid;  /* Remember rowid changes made by xFunc */
 
   /* If the function returned an error, throw an exception */
@@ -5504,6 +5512,7 @@ case OP_Program: {        /* jump */
   p->nCursor = (u16)pFrame->nChildCsr;
   p->apCsr = (VdbeCursor **)&aMem[p->nMem+1];
   p->aOp = aOp = pProgram->aOp;
+  pCtxOp = 0;
   p->nOp = pProgram->nOp;
   p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor];
   p->nOnceFlag = pProgram->nOnce;
@@ -5714,12 +5723,13 @@ case OP_AggStep: {
   Mem *pMem;
   Mem *pRec;
   Mem t;
-  sqlite3_context ctx;
+  sqlite3_context actx;
   sqlite3_value **apVal;
 
   n = pOp->p5;
   assert( n>=0 );
   pRec = &aMem[pOp->p2];
+  pCtxOp = 0;
   apVal = p->apArg;
   assert( apVal || n==0 );
   for(i=0; i<n; i++, pRec++){
@@ -5727,22 +5737,22 @@ case OP_AggStep: {
     apVal[i] = pRec;
     memAboutToChange(p, pRec);
   }
-  ctx.pFunc = pOp->p4.pFunc;
+  actx.pFunc = pOp->p4.pFunc;
   assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
-  ctx.pMem = pMem = &aMem[pOp->p3];
+  actx.pMem = pMem = &aMem[pOp->p3];
   pMem->n++;
   sqlite3VdbeMemInit(&t, db, MEM_Null);
-  ctx.pOut = &t;
-  ctx.isError = 0;
-  ctx.pVdbe = p;
-  ctx.iOp = (int)(pOp - aOp);
-  ctx.skipFlag = 0;
-  (ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */
-  if( ctx.isError ){
+  actx.pOut = &t;
+  actx.isError = 0;
+  actx.pVdbe = p;
+  actx.iOp = (int)(pOp - aOp);
+  actx.skipFlag = 0;
+  (actx.pFunc->xStep)(&actx, n, apVal); /* IMP: R-24505-23230 */
+  if( actx.isError ){
     sqlite3VdbeError(p, "%s", sqlite3_value_text(&t));
-    rc = ctx.isError;
+    rc = actx.isError;
   }
-  if( ctx.skipFlag ){
+  if( actx.skipFlag ){
     assert( pOp[-1].opcode==OP_CollSeq );
     i = pOp[-1].p1;
     if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1);
@@ -6172,6 +6182,7 @@ case OP_VFilter: {   /* jump */
   for(i = 0; i<nArg; i++){
     apArg[i] = &pArgc[i+1];
   }
+  pCtxOp = 0;
   rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
   sqlite3VtabImportErrmsg(p, pVtab);
   if( rc==SQLITE_OK ){
@@ -6355,6 +6366,7 @@ case OP_VUpdate: {
   if( ALWAYS(pModule->xUpdate) ){
     u8 vtabOnConflict = db->vtabOnConflict;
     apArg = p->apArg;
+    pCtxOp = 0;
     pX = &aMem[pOp->p3];
     for(i=0; i<nArg; i++){
       assert( memIsValid(pX) );