From: drh Date: Mon, 16 Nov 2009 02:14:00 +0000 (+0000) Subject: Optimizations to the sqlite3VdbeRecordCompare() routine help it to run 12.5% X-Git-Tag: fts3-refactor~1^2~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8b249a886d6933ad07f8a6e757245e48fabaa118;p=thirdparty%2Fsqlite.git Optimizations to the sqlite3VdbeRecordCompare() routine help it to run 12.5% faster for some traces. FossilOrigin-Name: 74c76f0bf946d184275de478ec72220d76342493 --- diff --git a/manifest b/manifest index 8823f66e92..e8549cb56b 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Optimizations\sto\sthe\smain\sloop\sinside\ssqlite3VdbeExec()\sto\shelp\sVDBE\sbyte\scode\nrun\sa\sfew\spercent\sfaster. -D 2009-11-14T23:22:23 +C Optimizations\sto\sthe\ssqlite3VdbeRecordCompare()\sroutine\shelp\sit\sto\srun\s12.5%\nfaster\sfor\ssome\straces. +D 2009-11-16T02:14:01 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 53f3dfa49f28ab5b80cb083fb7c9051e596bcfa1 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -214,7 +214,7 @@ F src/vdbe.c 0bc1c3aaa0c5c13240c2e39ce3b9ae92586fc30b F src/vdbe.h 5f35750615163d1064052785b4a9f0eb004a720d F src/vdbeInt.h d7ea821ac7813c9bea0fe87558c35e07b2c7c44d F src/vdbeapi.c 17680ab7a75ec938c5ba039a6c87489d01faf2cb -F src/vdbeaux.c 45d1e150d811da2bafe820136b1c21616b2e5fd4 +F src/vdbeaux.c d86062c20dd11f76d7e84148eb90ad2e67c692bd F src/vdbeblob.c 84f924700a7a889152aeebef77ca5f4e3875ffb4 F src/vdbemem.c 1e16e3a16e55f4c3452834f0e041726021aa66e0 F src/vtab.c 456fc226614569f0e46f216e33265bea268bd917 @@ -771,14 +771,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 8bd3cc82720ac7e8a9d4a03a882b6f8226867b0d -R cb3a1da29955733378e76881557b866a +P d622ac6ac7a297754494d3a33dbaeea02836272e +R 8a77d446e8971c8c821f82b0e714ed44 U drh -Z afa90cd668940f60ced698df17c38b7b +Z 16e3d159b2fe2d607c2cd029c6925807 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFK/zu0oxKgR168RlERAk/iAKCEVk6/+bUzTWEw8F/wvHvw0zgqfgCcC5l5 -k8ZGSZvLtvYXVF3tlPQ2ip8= -=cEZ3 +iD8DBQFLALVsoxKgR168RlERAuTkAJ9U+8DcIbrOHGi1j8U4oY3KYE4vIgCdGFuq +b9g15DE5dZ/IvtQYKf2f8vg= +=1X66 -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 1d5ac89ead..b6942d0e4f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d622ac6ac7a297754494d3a33dbaeea02836272e \ No newline at end of file +74c76f0bf946d184275de478ec72220d76342493 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 8dc4cf12d1..e8142f9058 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2788,8 +2788,16 @@ int sqlite3VdbeRecordCompare( mem1.enc = pKeyInfo->enc; mem1.db = pKeyInfo->db; mem1.flags = 0; - mem1.u.i = 0; /* not needed, here to silence compiler warning */ - mem1.zMalloc = 0; + VVA_ONLY( mem1.zMalloc = 0; ) /* Only used by assert() statements */ + + /* Compilers may complain that mem1.u.i is potentially uninitialized. + ** We could initialize it, as shown here, to silence those complaints. + ** But in fact, mem1.u.i will never actually be used initialized, and doing + ** the unnecessary initialization has a measurable negative performance + ** impact, since this routine is a very high runner. And so, we choose + ** to ignore the compiler warnings and leave this variable uninitialized. + */ + /* mem1.u.i = 0; // not needed, here to silence compiler warning */ idx1 = getVarint32(aKey1, szHdr1); d1 = szHdr1; @@ -2813,47 +2821,52 @@ int sqlite3VdbeRecordCompare( rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], iaColl[i] : 0); if( rc!=0 ){ - break; + assert( mem1.zMalloc==0 ); /* See comment below */ + + /* Invert the result if we are using DESC sort order. */ + if( pKeyInfo->aSortOrder && iaSortOrder[i] ){ + rc = -rc; + } + + /* If the PREFIX_SEARCH flag is set and all fields except the final + ** rowid field were equal, then clear the PREFIX_SEARCH flag and set + ** pPKey2->rowid to the value of the rowid field in (pKey1, nKey1). + ** This is used by the OP_IsUnique opcode. + */ + if( (pPKey2->flags & UNPACKED_PREFIX_SEARCH) && i==(pPKey2->nField-1) ){ + assert( idx1==szHdr1 && rc ); + assert( mem1.flags & MEM_Int ); + pPKey2->flags &= ~UNPACKED_PREFIX_SEARCH; + pPKey2->rowid = mem1.u.i; + } + + return rc; } i++; } - /* No memory allocation is ever used on mem1. */ - if( NEVER(mem1.zMalloc) ) sqlite3VdbeMemRelease(&mem1); - - /* If the PREFIX_SEARCH flag is set and all fields except the final - ** rowid field were equal, then clear the PREFIX_SEARCH flag and set - ** pPKey2->rowid to the value of the rowid field in (pKey1, nKey1). - ** This is used by the OP_IsUnique opcode. + /* No memory allocation is ever used on mem1. Prove this using + ** the following assert(). If the assert() fails, it indicates a + ** memory leak and a need to call sqlite3VdbeMemRelease(&mem1). */ - if( (pPKey2->flags & UNPACKED_PREFIX_SEARCH) && i==(pPKey2->nField-1) ){ - assert( idx1==szHdr1 && rc ); - assert( mem1.flags & MEM_Int ); - pPKey2->flags &= ~UNPACKED_PREFIX_SEARCH; - pPKey2->rowid = mem1.u.i; - } - - if( rc==0 ){ - /* rc==0 here means that one of the keys ran out of fields and - ** all the fields up to that point were equal. If the UNPACKED_INCRKEY - ** flag is set, then break the tie by treating key2 as larger. - ** If the UPACKED_PREFIX_MATCH flag is set, then keys with common prefixes - ** are considered to be equal. Otherwise, the longer key is the - ** larger. As it happens, the pPKey2 will always be the longer - ** if there is a difference. - */ - if( pPKey2->flags & UNPACKED_INCRKEY ){ - rc = -1; - }else if( pPKey2->flags & UNPACKED_PREFIX_MATCH ){ - /* Leave rc==0 */ - }else if( idx1aSortOrder && inField - && pKeyInfo->aSortOrder[i] ){ - rc = -rc; + assert( mem1.zMalloc==0 ); + + /* rc==0 here means that one of the keys ran out of fields and + ** all the fields up to that point were equal. If the UNPACKED_INCRKEY + ** flag is set, then break the tie by treating key2 as larger. + ** If the UPACKED_PREFIX_MATCH flag is set, then keys with common prefixes + ** are considered to be equal. Otherwise, the longer key is the + ** larger. As it happens, the pPKey2 will always be the longer + ** if there is a difference. + */ + assert( rc==0 ); + if( pPKey2->flags & UNPACKED_INCRKEY ){ + rc = -1; + }else if( pPKey2->flags & UNPACKED_PREFIX_MATCH ){ + /* Leave rc==0 */ + }else if( idx1