Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Improvements to comments. Minor changes to code in the hot path of OP_Column - with the hope of get a few cycles of performance improvement. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | faster-typeof-and-length |
Files: | files | file ages | folders |
SHA1: |
ca093103437f141caa3eb11539c6eb7b |
User & Date: | drh 2012-03-28 13:41:10.884 |
Context
2012-03-28
| ||
16:14 | Minor changes to the core of OP_Column for performance and to clarify the critical path. (Closed-Leaf check-in: 868394761e user: drh tags: faster-typeof-and-length) | |
15:44 | This change turned out to the code slower. Side track it. Was: Tweaks to the OP_Column opcode for clarity of presentation. (Closed-Leaf check-in: 4d516240d2 user: drh tags: mistake) | |
13:41 | Improvements to comments. Minor changes to code in the hot path of OP_Column - with the hope of get a few cycles of performance improvement. (check-in: ca09310343 user: drh tags: faster-typeof-and-length) | |
02:51 | Test cases for length() of a large blob in an aggregate query. (check-in: d095fa4bfa user: drh tags: faster-typeof-and-length) | |
Changes
Changes to src/vdbe.c.
︙ | ︙ | |||
2124 2125 2126 2127 2128 2129 2130 | ** the result. ** ** If the OPFLAG_CLEARCACHE bit is set on P5 and P1 is a pseudo-table cursor, ** then the cache of the cursor is reset prior to extracting the column. ** The first OP_Column against a pseudo-table after the value of the content ** register has changed should have this bit set. ** | | | | | | 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 | ** the result. ** ** If the OPFLAG_CLEARCACHE bit is set on P5 and P1 is a pseudo-table cursor, ** then the cache of the cursor is reset prior to extracting the column. ** The first OP_Column against a pseudo-table after the value of the content ** register has changed should have this bit set. ** ** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 when ** the result is guaranteed to only be used as the argument of a length() ** or typeof() function, respectively. The loading of large blobs can be ** skipped for length() and all content loading can be skipped for typeof(). */ case OP_Column: { u32 payloadSize; /* Number of bytes in the record */ i64 payloadSize64; /* Number of bytes in the record */ int p1; /* P1 value of the opcode */ int p2; /* column number to retrieve */ VdbeCursor *pC; /* The VDBE cursor */ |
︙ | ︙ | |||
2268 2269 2270 2271 2272 2273 2274 | if( payloadSize <= (u32)avail ){ zRec = zData; pC->aRow = (u8*)zData; }else{ pC->aRow = 0; } } | | | 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 | if( payloadSize <= (u32)avail ){ zRec = zData; pC->aRow = (u8*)zData; }else{ pC->aRow = 0; } } /* The following assert is true in all cases except when ** the database file has been corrupted externally. ** assert( zRec!=0 || avail>=payloadSize || avail>=9 ); */ szHdr = getVarint32((u8*)zData, offset); /* Make sure a corrupt database has not given us an oversize header. ** Do this now to avoid an oversize memory allocation. ** |
︙ | ︙ | |||
2343 2344 2345 2346 2347 2348 2349 | szField = sqlite3VdbeSerialTypeLen(t); offset += szField; if( offset<szField ){ /* True if offset overflows */ zIdx = &zEndHdr[1]; /* Forces SQLITE_CORRUPT return below */ break; } }else{ | | | | | 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 | szField = sqlite3VdbeSerialTypeLen(t); offset += szField; if( offset<szField ){ /* True if offset overflows */ zIdx = &zEndHdr[1]; /* Forces SQLITE_CORRUPT return below */ break; } }else{ /* If i is less that nField, then there are fewer fields in this ** record than SetNumColumns indicated there are columns in the ** table. Set the offset for any extra columns not present in ** the record to 0. This tells code below to store the default value ** for the column instead of deserializing a value from the record. */ aOffset[i] = 0; } } sqlite3VdbeMemRelease(&sMem); sMem.flags = MEM_Null; |
︙ | ︙ | |||
2380 2381 2382 2383 2384 2385 2386 | */ if( aOffset[p2] ){ assert( rc==SQLITE_OK ); if( zRec ){ VdbeMemRelease(pDest); sqlite3VdbeSerialGet((u8 *)&zRec[aOffset[p2]], aType[p2], pDest); }else{ | > | | | | | 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 | */ if( aOffset[p2] ){ assert( rc==SQLITE_OK ); if( zRec ){ VdbeMemRelease(pDest); sqlite3VdbeSerialGet((u8 *)&zRec[aOffset[p2]], aType[p2], pDest); }else{ t = aType[p2]; len = sqlite3VdbeSerialTypeLen(t); if( (pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0 && ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0) ){ /* Content is irrelevant for the typeof() function and for ** the length(X) function if X is a blob. So we might as well use ** bogus content rather than reading content from disk. NULL works ** for text and blob and whatever is in the payloadSize64 variable ** will work for everything else. */ zData = t<12 ? (char*)&payloadSize64 : 0; }else{ sqlite3VdbeMemMove(&sMem, pDest); rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->isIndex, &sMem); if( rc!=SQLITE_OK ){ goto op_column_out; } zData = sMem.z; } sqlite3VdbeSerialGet((u8*)zData, t, pDest); } pDest->enc = encoding; }else{ if( pOp->p4type==P4_MEM ){ sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static); }else{ MemSetTypeFlag(pDest, MEM_Null); |
︙ | ︙ |