Performance improvements to the comparison operators in the bytecode engine.

FossilOrigin-Name: 37803b19d219f4107f29b240d5d314600e4bd236
This commit is contained in:
drh 2016-09-09 19:33:00 +00:00
parent b80dbdc2f7
commit 64caee4086
4 changed files with 53 additions and 18 deletions

View File

@ -1,5 +1,5 @@
C Fix\sa\sout-of-order\svariable\sdeclaration\sfor\ssome\scompile-time\sconfigurations.
D 2016-09-09T15:12:41.801
C Performance\simprovements\sto\sthe\scomparison\soperators\sin\sthe\sbytecode\sengine.
D 2016-09-09T19:33:00.624
F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c
@ -452,11 +452,11 @@ F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d
F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3
F src/vdbe.c 3148d5d47816c5ad2ed3c62beb3086cbbcaab107
F src/vdbe.c 2087dfd6f013a9c808c92f8713fd8c7c62be2857
F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10
F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d
F src/vdbeapi.c a32d61b7dd05e6890d8fd44d2805f55e2f5ba9f3
F src/vdbeaux.c 83458783d241cfd6691141c8a105832ee50258e5
F src/vdbeaux.c 230b6826656144bcdca6d9c09d38da9d927739be
F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937
F src/vdbemem.c e67dc6d8177fd1830efb5d15e17793408251a187
F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c
@ -1523,7 +1523,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 2bdd838e2c434f1d26b1836ef39fa938ef93131d
R cdaf391119a3a76bb49bf405a13f8694
P 6ac932c92a61cd68cc5b1816216e4748a5c7b3cd
R f1fdb6c44ee59a1a70f4ca210b22ee73
U drh
Z f913482662ff429e344c363b85d81ce9
Z 14efbbb4d9b59bda04ac0672b03a8c5e

View File

@ -1 +1 @@
6ac932c92a61cd68cc5b1816216e4748a5c7b3cd
37803b19d219f4107f29b240d5d314600e4bd236

View File

@ -2035,12 +2035,21 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
if( (flags1 | flags3)&MEM_Str ){
if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn1,0);
testcase( flags3!=pIn3->flags ); /* Possible if pIn1==pIn3 */
flags3 = pIn3->flags;
}
if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn3,0);
}
}
/* Handle the common case of integer comparison here, as an
** optimization, to avoid a call to sqlite3MemCompare() */
if( (pIn1->flags & pIn3->flags & MEM_Int)!=0 ){
if( pIn3->u.i > pIn1->u.i ){ res = +1; goto compare_op; }
if( pIn3->u.i < pIn1->u.i ){ res = -1; goto compare_op; }
res = 0;
goto compare_op;
}
}else if( affinity==SQLITE_AFF_TEXT ){
if( (flags1 & MEM_Str)==0 && (flags1 & (MEM_Int|MEM_Real))!=0 ){
testcase( pIn1->flags & MEM_Int );
@ -2048,6 +2057,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
sqlite3VdbeMemStringify(pIn1, encoding, 1);
testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) );
flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
testcase( flags3!=pIn3->flags ); /* Possible if pIn1==pIn3 */
flags3 = pIn3->flags;
}
if( (flags3 & MEM_Str)==0 && (flags3 & (MEM_Int|MEM_Real))!=0 ){
@ -2059,16 +2069,9 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
}
}
assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
if( flags1 & MEM_Zero ){
sqlite3VdbeMemExpandBlob(pIn1);
flags1 &= ~MEM_Zero;
}
if( flags3 & MEM_Zero ){
sqlite3VdbeMemExpandBlob(pIn3);
flags3 &= ~MEM_Zero;
}
res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
}
compare_op:
switch( pOp->opcode ){
case OP_Eq: res2 = res==0; break;
case OP_Ne: res2 = res; break;

View File

@ -3716,15 +3716,47 @@ static int vdbeCompareMemString(
}
}
/*
** The input pBlob is guaranteed to be a Blob that is not marked
** with MEM_Zero. Return true if it could be a zero-blob.
*/
static int isZeroBlob(const Mem *pBlob){
int i;
for(i=0; i<pBlob->n && pBlob->z[i]==0; i++){}
return i==pBlob->n;
}
/*
** Compare two blobs. Return negative, zero, or positive if the first
** is less than, equal to, or greater than the second, respectively.
** If one blob is a prefix of the other, then the shorter is the lessor.
*/
static SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){
int c = memcmp(pB1->z, pB2->z, pB1->n>pB2->n ? pB2->n : pB1->n);
int c;
int n1 = pB1->n;
int n2 = pB2->n;
/* It is possible to have a Blob value that has some non-zero content
** followed by zero content. But that only comes up for Blobs formed
** by the OP_MakeRecord opcode, and such Blobs never get passed into
** sqlite3MemCompare(). */
assert( (pB1->flags & MEM_Zero)==0 || n1==0 );
assert( (pB2->flags & MEM_Zero)==0 || n2==0 );
if( (pB1->flags|pB2->flags) & MEM_Zero ){
if( pB1->flags & pB2->flags & MEM_Zero ){
return pB1->u.nZero - pB2->u.nZero;
}else if( pB1->flags & MEM_Zero ){
if( !isZeroBlob(pB2) ) return -1;
return pB1->u.nZero - n2;
}else{
if( !isZeroBlob(pB1) ) return +1;
return n1 - pB2->u.nZero;
}
}
c = memcmp(pB1->z, pB2->z, n1>n2 ? n2 : n1);
if( c ) return c;
return pB1->n - pB2->n;
return n1 - n2;
}
/*