Add the OPFLAG_MULTICOLUMN flat to the OP_Column opcode. Rearrange OP_Column
instrunctions to take advantage of the new flag for a small performance increase FossilOrigin-Name: 5e5d6e8680b253b4de5c04df155c27f15fedc0c1
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
C Fix\sthe\sheader\scomment\sin\ssqlite3VdbeDeletePriorOpcode().\s\sNo\schanges\sto\ncode.
|
||||
D 2014-09-29T15:42:01.115
|
||||
C Add\sthe\sOPFLAG_MULTICOLUMN\sflat\sto\sthe\sOP_Column\sopcode.\s\sRearrange\sOP_Column\ninstrunctions\sto\stake\sadvantage\sof\sthe\snew\sflag\sfor\sa\ssmall\sperformance\s\nincrease
|
||||
D 2014-09-29T18:47:20.017
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@@ -181,7 +181,7 @@ F src/complete.c 535183afb3c75628b78ce82612931ac7cdf26f14
|
||||
F src/ctime.c bb434068b5308a857b181c2d204a320ff0d6c638
|
||||
F src/date.c 57a7f9ba9f6b4d5268f5e411739066a611f99036
|
||||
F src/delete.c fae81cc2eb14b75267d4f47d3cfc9ae02aae726f
|
||||
F src/expr.c f32119248996680aa73c5c37bfdd42820804dc17
|
||||
F src/expr.c 622ca88bb258292690a550ca0c290ec7b071bed4
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c da985ae673efef2c712caef825a5d2edb087ead7
|
||||
F src/func.c ba47c1671ab3cfdafa6e9d6ee490939ea578adee
|
||||
@@ -227,12 +227,12 @@ F src/printf.c 3a47f526b173813d9a7f4e7044007771ba68cde1
|
||||
F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
|
||||
F src/resolve.c a3466128b52a86c466e47ac1a19e2174f7b5cf89
|
||||
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
||||
F src/select.c a83ed8bc2a31c131e3addb6f0488b68334085e7b
|
||||
F src/select.c 6e7d7a277307ebee1a284d8811a8a3351ffc39b2
|
||||
F src/shell.c dad23987c34faddb061a339da3e92e05ccc6935e
|
||||
F src/sqlite.h.in 8b018219ce988913e5977d5de9ab4beb33be23b6
|
||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
|
||||
F src/sqliteInt.h 5e09fe04f999223680801ddf8fbae6b60751d613
|
||||
F src/sqliteInt.h ba443d9af2cef399e2ec641d44d005212b1476ef
|
||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
|
||||
F src/table.c 2e99ef7ef16187e17033d9398dc962ce22dab5cb
|
||||
@@ -285,15 +285,15 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c 22dded4283dc4b25422f6444cdcb8d6b1ea0b5ff
|
||||
F src/tokenize.c cc9016e5007fc5e76789079616d2f26741bcc689
|
||||
F src/trigger.c 25571661fdeae8c7f975ff40ffec205520a3f92f
|
||||
F src/update.c 729f6f18fc27740591d085e1172cebe311144bf0
|
||||
F src/update.c dcc1733c8f9d455a3127e2b151a211fa7f9ef053
|
||||
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
|
||||
F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8
|
||||
F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a
|
||||
F src/vdbe.c 93eeb6f9c3a3084133225a196f220454d71cca10
|
||||
F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327
|
||||
F src/vdbe.c 89636b004debc955452f6e0f26dfcc13cc96676b
|
||||
F src/vdbe.h d5825ae515ab108331739bd4910eb66dd0eb33f0
|
||||
F src/vdbeInt.h bb7f7ecfdead1a2ae0251b59f86f5724838d975c
|
||||
F src/vdbeapi.c e9e33b59834e3edc8790209765e069874c269d9d
|
||||
F src/vdbeaux.c 8e016c6051c013a394f8e8679be1ca60723707bd
|
||||
F src/vdbeaux.c f8df1050cb0e5f7d537bda4dc6caa44d44ab87bc
|
||||
F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4
|
||||
F src/vdbemem.c 1e105dacf5190fc85a8ec2107c0dcc1884e75099
|
||||
F src/vdbesort.c 5c1bacf90578d22b630fbf6ed98ccf60d83435ef
|
||||
@@ -1200,7 +1200,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P 414f0d6a647a4d040b5463c73c5e15e699d85b4c
|
||||
R f6298f1a1c0cd9e9dc9c3dc07f24407e
|
||||
P 7fb1626866c2f8dad84c7e6184824be3efd71ca2
|
||||
R 58d61b9e8ed6b972c827aa4b2de6a9d8
|
||||
T *branch * faster-OP_Column
|
||||
T *sym-faster-OP_Column *
|
||||
T -sym-trunk *
|
||||
U drh
|
||||
Z 0f82639c06e932d5523a9215bf58cd9c
|
||||
Z bc7d4115a8f75585e68aa7b7bc067fe4
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
7fb1626866c2f8dad84c7e6184824be3efd71ca2
|
||||
5e5d6e8680b253b4de5c04df155c27f15fedc0c1
|
||||
@@ -2381,6 +2381,7 @@ void sqlite3ExprCodeGetColumnOfTable(
|
||||
}
|
||||
if( iCol>=0 ){
|
||||
sqlite3ColumnDefault(v, pTab, iCol, regOut);
|
||||
sqlite3VdbeOptimizeColumnOpcodes(v);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -706,7 +706,7 @@ static void selectInnerLoop(
|
||||
pDest->nSdst = nResultCol;
|
||||
regResult = pDest->iSdst;
|
||||
if( srcTab>=0 ){
|
||||
for(i=0; i<nResultCol; i++){
|
||||
for(i=nResultCol-1; i>=0; i--){
|
||||
sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i);
|
||||
VdbeComment((v, "%s", pEList->a[i].zName));
|
||||
}
|
||||
@@ -1225,10 +1225,11 @@ static void generateSortTail(
|
||||
p5 = 0;
|
||||
bSeq = 1;
|
||||
}
|
||||
for(i=0; i<nSortData; i++){
|
||||
for(i=nSortData-1; i>=0; i--){
|
||||
sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i);
|
||||
if( i==0 ) sqlite3VdbeChangeP5(v, p5);
|
||||
sqlite3VdbeChangeP5(v, p5);
|
||||
VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
|
||||
p5 = 0;
|
||||
}
|
||||
switch( eDest ){
|
||||
case SRT_Table:
|
||||
|
||||
@@ -2665,6 +2665,7 @@ struct AuthContext {
|
||||
#define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */
|
||||
#define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */
|
||||
#define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */
|
||||
#define OPFLAG_MULTICOLUMN 0x10 /* OP_Column followed by another */
|
||||
|
||||
/*
|
||||
* Each trigger present in the database schema is stored as an instance of
|
||||
|
||||
@@ -73,6 +73,7 @@ void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
|
||||
}
|
||||
#ifndef SQLITE_OMIT_FLOATING_POINT
|
||||
if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
|
||||
sqlite3VdbeOptimizeColumnOpcodes(v);
|
||||
sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
|
||||
}
|
||||
#endif
|
||||
|
||||
+33
-4
@@ -2266,9 +2266,11 @@ case OP_Column: {
|
||||
u32 avail; /* Number of bytes of available data */
|
||||
u32 t; /* A type code from the record header */
|
||||
u16 fx; /* pDest->flags value */
|
||||
u8 p5;
|
||||
Mem *pReg; /* PseudoTable input register */
|
||||
|
||||
p2 = pOp->p2;
|
||||
p5 = 0;
|
||||
assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
|
||||
pDest = &aMem[pOp->p3];
|
||||
memAboutToChange(p, pDest);
|
||||
@@ -2436,22 +2438,32 @@ case OP_Column: {
|
||||
}
|
||||
}
|
||||
|
||||
/* Extract the content for the p2+1-th column. Control can only
|
||||
** reach this point if aOffset[p2], aOffset[p2+1], and pC->aType[p2] are
|
||||
** all valid.
|
||||
/* At this point, all of the following values are set:
|
||||
**
|
||||
** p2 Index of column to extract. pOp->p2.
|
||||
** pDest Memory register into which to write result
|
||||
** pC->aRow Binary row content from the btree. Might be incomplete
|
||||
** pC->szRow Number of bytes in pC->szRow
|
||||
** aOffset[p2] Offset into the binary row where P2-th column starts
|
||||
** aOffste[p2+1] Offset into binary row of first byte past P2-th column
|
||||
** pC->aType[p2] Datatype of the P2-th column (as stored on disk)
|
||||
**
|
||||
** Extract the content for column number p2.
|
||||
*/
|
||||
op_column_decode:
|
||||
assert( p2<pC->nHdrParsed );
|
||||
assert( rc==SQLITE_OK );
|
||||
assert( sqlite3VdbeCheckMemInvariants(pDest) );
|
||||
if( VdbeMemDynamic(pDest) ) sqlite3VdbeMemSetNull(pDest);
|
||||
t = pC->aType[p2];
|
||||
p5 = pOp->p5;
|
||||
if( pC->szRow>=aOffset[p2+1] ){
|
||||
/* This is the common case where the desired content fits on the original
|
||||
** page - where the content is not on an overflow page */
|
||||
sqlite3VdbeSerialGet(pC->aRow+aOffset[p2], t, pDest);
|
||||
}else{
|
||||
/* This branch happens only when content is on overflow pages */
|
||||
if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0
|
||||
if( ((p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0
|
||||
&& ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0))
|
||||
|| (len = sqlite3VdbeSerialTypeLen(t))==0
|
||||
){
|
||||
@@ -2495,6 +2507,23 @@ op_column_out:
|
||||
op_column_error:
|
||||
UPDATE_MAX_BLOBSIZE(pDest);
|
||||
REGISTER_TRACE(pOp->p3, pDest);
|
||||
|
||||
/* If the OPFLAG_MULTICOLUMN bit is set on P5, that means that this
|
||||
** OP_Column is immediately followed by another OP_Column with the same
|
||||
** P1 and a P2 that is no larger than the current P2. In that case,
|
||||
** process the following OP_Column as part of this instruction, without
|
||||
** returning to the main instruction dispatch loop.
|
||||
*/
|
||||
if( (p5 & OPFLAG_MULTICOLUMN)!=0 && rc==0 ){
|
||||
pc++;
|
||||
assert( pOp[1].opcode==OP_Column );
|
||||
assert( pOp[1].p1==pOp[0].p1 );
|
||||
assert( pOp[1].p2<=pOp[0].p2 );
|
||||
pOp++;
|
||||
p2 = pOp->p2;
|
||||
pDest = &aMem[pOp->p3];
|
||||
goto op_column_decode;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -179,6 +179,7 @@ void sqlite3VdbeChangeP5(Vdbe*, u8 P5);
|
||||
void sqlite3VdbeJumpHere(Vdbe*, int addr);
|
||||
void sqlite3VdbeChangeToNoop(Vdbe*, int addr);
|
||||
int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op);
|
||||
void sqlite3VdbeOptimizeColumnOpcodes(Vdbe*);
|
||||
void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
|
||||
void sqlite3VdbeSetP4KeyInfo(Parse*, Index*);
|
||||
void sqlite3VdbeUsesBtree(Vdbe*, int);
|
||||
|
||||
@@ -502,6 +502,15 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
|
||||
pOp->p4type = P4_ADVANCE;
|
||||
break;
|
||||
}
|
||||
case OP_Column: {
|
||||
if( pOp[1].opcode==OP_Column
|
||||
&& pOp[1].p1==pOp->p1
|
||||
&& pOp[1].p2<=pOp->p2
|
||||
){
|
||||
pOp->p5 |= OPFLAG_MULTICOLUMN;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pOp->opflags = sqlite3OpcodeProperty[opcode];
|
||||
@@ -764,6 +773,30 @@ int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** When running multiple OP_Column opcodes in a row, it is advantagous
|
||||
** to run the one with the largest P2 value (the largest column number)
|
||||
** first. This routine checks the last few OP_Column opcodes and
|
||||
** might reorder them so that a larger P2 value opertion occurs at
|
||||
** the start of the list.
|
||||
*/
|
||||
void sqlite3VdbeOptimizeColumnOpcodes(Vdbe *p){
|
||||
VdbeOp *aOp, tempOp;
|
||||
int i;
|
||||
aOp = p->aOp;
|
||||
i = p->nOp-2;
|
||||
while( i>p->pParse->iFixedOp
|
||||
&& aOp[i+1].opcode==OP_Column
|
||||
&& aOp[i].opcode==OP_Column
|
||||
&& aOp[i].p1==aOp[i+1].p1
|
||||
&& aOp[i].p2<aOp[i+1].p2 ){
|
||||
tempOp = aOp[i];
|
||||
aOp[i] = aOp[i+1];
|
||||
aOp[i+1] = tempOp;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Change the value of the P4 operand for a specific instruction.
|
||||
** This routine is useful when a large program is loaded from a
|
||||
|
||||
Reference in New Issue
Block a user