Compare commits

...

1 Commits

Author SHA1 Message Date
drh f14c59bb11 Cache the most recently sqlite3_context used by OP_Function and reuse it on
subsequent calls, if appropriate. This gives a noticable performance boost.

FossilOrigin-Name: 2f31bdd1b2186659f57a705ecf0eaf590471c374
2015-06-26 13:31:02 +00:00
3 changed files with 54 additions and 39 deletions
+9 -6
View File
@@ -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
+1 -1
View File
@@ -1 +1 @@
015302f15e46a087ec92f3644c6741600dbf4306
2f31bdd1b2186659f57a705ecf0eaf590471c374
+44 -32
View 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);
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++){
assert( memIsValid(pArg) );
apVal[i] = pArg;
Deephemeralize(pArg);
REGISTER_TRACE(pOp->p2+i, pArg);
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) );