1
0
mirror of https://github.com/sqlite/sqlite.git synced 2026-10-23 21:49:02 +03:00

Speed up substr() start scanning for ASCII text

Skip bounded groups of eight nonzero ASCII bytes while advancing the start position. Keep the existing scalar handling for NUL, non-ASCII bytes, and short tails.


FossilOrigin-Name: 5749b0489c50a9ea3ee576cb565810cb2f6d766635c6f1dd38cdc65a76a6d237
This commit is contained in:
jeffchen
2026-10-12 22:38:23 +00:00
parent 9d7c5b1472
commit 5e19f7e4bb
4 changed files with 35 additions and 10 deletions

View File

@@ -1,5 +1,5 @@
C Merge\srecent\sbranch-3.54\sfixes\sinto\strunk.
D 2026-10-12T12:51:45.528
C Speed\sup\ssubstr()\sstart\sscanning\sfor\sASCII\stext\n\nSkip\sbounded\sgroups\sof\seight\snonzero\sASCII\sbytes\swhile\sadvancing\sthe\sstart\sposition.\sKeep\sthe\sexisting\sscalar\shandling\sfor\sNUL,\snon-ASCII\sbytes,\sand\sshort\stails.\n
D 2026-10-12T22:38:23.189
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -757,7 +757,7 @@ F src/delete.c 59eeca3fb88c29329afc41bb803ee568b120d9dd7470b5f38ab55cc38390b451
F src/expr.c 874e2907699dd181a7baee4941c1f2ee7b86ca5f2c0cf6163e6d89146f47cb38
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c 26788ae6c785d70f9829c4176e9764447014fc73e6ba31e9f1881720a64ae7f1
F src/func.c 54d96eeafcb6ec4cff92028ea0f7bb09e27b375b248d969aeb80a61e560ef302
F src/func.c 9372b65d0e5e6fc9fff7c4fc20558c5e68babcc7f54f033bba67da39f47acc37
F src/global.c 7eea537ac0c113ac55cb2dd4d8fc2a6a91ae478be34231b4efaffc46817fee85
F src/hash.c 03c8c0f4be9e8bcb6de65aa26d34a61d48a9430747084a69f9469fbb00ea52ca
F src/hash.h 46b92795a95bfefb210f52f0c316e9d7cdbcdd7e7fcfb0d8be796d3a5767cddf
@@ -2284,8 +2284,11 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
P 85adb10e22ac33500f974d756bcf1fac46b7d98868cb4e00e59f30c075001b5b af570c8fc22dc682ab71d8e97c20268971fb33032530d3fa9908e1995bed529e
R 99ee32c98dc326807c59b15ba4b8a633
U drh
Z 909700f48f5b4fd3ed90f4021834fc08
P a9d8cddccc77bf6c09531e1051eba36f1bd2e95c4e62921c07c4772f12f351ca
R a449b0d474f3b3bfc313835c8a117209
T *branch * opt-substr-ascii8
T *sym-opt-substr-ascii8 *
T -sym-trunk *
U jeffchen
Z 773054ce143461c3d197b92e5707954c
# Remove this line to create a well-formed Fossil manifest.

View File

@@ -1,2 +1,2 @@
branch trunk
tag trunk
branch opt-substr-ascii8
tag opt-substr-ascii8

View File

@@ -1 +1 @@
a9d8cddccc77bf6c09531e1051eba36f1bd2e95c4e62921c07c4772f12f351ca
5749b0489c50a9ea3ee576cb565810cb2f6d766635c6f1dd38cdc65a76a6d237

View File

@@ -333,6 +333,14 @@ static void printfFunc(
}
}
/* Return true if any of the eight bytes in word is NUL or non-ASCII. */
static SQLITE_INLINE int containsNulOrNonAscii(u64 word){
const u64 byteOnes = UINT64_C(0x0101010101010101);
const u64 byteHighBits = UINT64_C(0x8080808080808080);
/* NUL causes a borrow into a high bit; non-ASCII already has one set. */
return ((word | (word - byteOnes)) & byteHighBits)!=0;
}
/*
** Implementation of the substr() function.
**
@@ -416,6 +424,20 @@ static void substrFunc(
}
assert( p1>=0 && p2>=0 );
if( p0type!=SQLITE_BLOB ){
if( p1>=8 ){
/* Skip 8 characters at a time while all 8 bytes are in 0x01..0x7f */
const unsigned char *zEnd = z + sqlite3_value_bytes(argv[0]);
while( p1>=8 && zEnd-z>=8 ){
u64 word;
memcpy(&word, z, sizeof(word));
/* Handle NUL and UTF-8 with the scalar loop below. */
if( containsNulOrNonAscii(word) ){
break;
}
z += 8;
p1 -= 8;
}
}
for( ; p1>0; p1--){
/* vvvvvv---- See tag-20260418-01 */
if( (u8)(z[0]-1)<(0x80-1) ){