Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Performance improvements and size reductions on the OP_Seek* family of VDBE opcodes. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
ed820f45cf4354b1e1db64049c47a072 |
User & Date: | drh 2009-11-13 20:52:44.000 |
Context
2009-11-14
| ||
18:04 | Make the sqlite3VdbeExec() function about 2% faster by storing the opcode array in a local variable. (check-in: 8bd3cc8272 user: drh tags: trunk) | |
2009-11-13
| ||
20:52 | Performance improvements and size reductions on the OP_Seek* family of VDBE opcodes. (check-in: ed820f45cf user: drh tags: trunk) | |
19:43 | Simplify the OPFLG processing logic in the VDBE for a speed boost in the VDBE processing loop and a reduction in code size. (check-in: 3352b3eba5 user: drh tags: trunk) | |
Changes
Changes to src/vdbe.c.
︙ | ︙ | |||
3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 | i64 iKey; /* The rowid we are to seek to */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p2!=0 ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pC->pseudoTableReg==0 ); if( pC->pCursor!=0 ){ oc = pOp->opcode; pC->nullRow = 0; if( pC->isTable ){ /* The input value in P3 might be of any type: integer, real, string, ** blob, or NULL. But it needs to be an integer before we can do ** the seek, so covert it. */ | > > > | 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 | i64 iKey; /* The rowid we are to seek to */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p2!=0 ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pC->pseudoTableReg==0 ); assert( OP_SeekLe == OP_SeekLt+1 ); assert( OP_SeekGe == OP_SeekLt+2 ); assert( OP_SeekGt == OP_SeekLt+3 ); if( pC->pCursor!=0 ){ oc = pOp->opcode; pC->nullRow = 0; if( pC->isTable ){ /* The input value in P3 might be of any type: integer, real, string, ** blob, or NULL. But it needs to be an integer before we can do ** the seek, so covert it. */ |
︙ | ︙ | |||
3204 3205 3206 3207 3208 3209 3210 | assert( (pIn3->flags & MEM_Real)!=0 ); if( iKey==SMALLEST_INT64 && (pIn3->r<(double)iKey || pIn3->r>0) ){ /* The P3 value is too large in magnitude to be expressed as an ** integer. */ res = 1; if( pIn3->r<0 ){ | | | | 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 | assert( (pIn3->flags & MEM_Real)!=0 ); if( iKey==SMALLEST_INT64 && (pIn3->r<(double)iKey || pIn3->r>0) ){ /* The P3 value is too large in magnitude to be expressed as an ** integer. */ res = 1; if( pIn3->r<0 ){ if( oc>=OP_SeekGe ){ assert( oc==OP_SeekGe || oc==OP_SeekGt ); rc = sqlite3BtreeFirst(pC->pCursor, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; } }else{ if( oc<=OP_SeekLe ){ assert( oc==OP_SeekLt || oc==OP_SeekLe ); rc = sqlite3BtreeLast(pC->pCursor, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; } } if( res ){ pc = pOp->p2 - 1; } |
︙ | ︙ | |||
3241 3242 3243 3244 3245 3246 3247 | } }else{ nField = pOp->p4.i; assert( pOp->p4type==P4_INT32 ); assert( nField>0 ); r.pKeyInfo = pC->pKeyInfo; r.nField = (u16)nField; | > > | | | | > > > > > > > | | | 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 | } }else{ nField = pOp->p4.i; assert( pOp->p4type==P4_INT32 ); assert( nField>0 ); r.pKeyInfo = pC->pKeyInfo; r.nField = (u16)nField; /* The next line of code computes as follows, only faster: ** if( oc==OP_SeekGt || oc==OP_SeekLe ){ ** r.flags = UNPACKED_INCRKEY; ** }else{ ** r.flags = 0; ** } */ r.flags = UNPACKED_INCRKEY * (1 & (oc - OP_SeekLt)); assert( oc!=OP_SeekGt || r.flags==UNPACKED_INCRKEY ); assert( oc!=OP_SeekLe || r.flags==UNPACKED_INCRKEY ); assert( oc!=OP_SeekGe || r.flags==0 ); assert( oc!=OP_SeekLt || r.flags==0 ); r.aMem = &p->aMem[pOp->p3]; rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, &r, 0, 0, &res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } pC->rowidIsValid = 0; } pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; #ifdef SQLITE_TEST sqlite3_search_count++; #endif if( oc>=OP_SeekGe ){ assert( oc==OP_SeekGe || oc==OP_SeekGt ); if( res<0 || (res==0 && oc==OP_SeekGt) ){ rc = sqlite3BtreeNext(pC->pCursor, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; pC->rowidIsValid = 0; }else{ res = 0; } |
︙ | ︙ |