From 4adc4cb93b4d111c37b52b2b8590bdf91437e111 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 11 Nov 2009 20:53:31 +0000 Subject: [PATCH] Tweaks to the SUBSTR() function to make it dramatically faster in the common case where the input string is large but the 2nd and 3rd arguments are small positive integers. FossilOrigin-Name: 5a474a867c5988ad5ec03719516fdd38f0da5c2c --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/func.c | 16 +++++++++------- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 9c937841a0..f7b1f32f51 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Allow\smedia\ssector\ssizes\sas\ssmall\sas\s32.\s\sThe\sformer\sminimum\ssize\swas\s512. -D 2009-11-11T13:17:08 +C Tweaks\sto\sthe\sSUBSTR()\sfunction\sto\smake\sit\sdramatically\sfaster\sin\sthe\scommon\ncase\swhere\sthe\sinput\sstring\sis\slarge\sbut\sthe\s2nd\sand\s3rd\sarguments\sare\ssmall\npositive\sintegers. +D 2009-11-11T20:53:31 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 53f3dfa49f28ab5b80cb083fb7c9051e596bcfa1 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -120,7 +120,7 @@ F src/delete.c ec04635d152debdab70d4b30c5516b59282075ea F src/expr.c be605c60ff84699f3087209f2f86a140a6a5e96c F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 41219cba186bcf0a053e42327dfa23aaba4f834a -F src/func.c 5949e2633bb8ff57cc70c1904db171ba23f13537 +F src/func.c 97cb15ef7a7c32293a938589c9eb6933f6688a21 F src/global.c 271952d199a8cc59d4ce840b3bbbfd2f30c8ba32 F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 @@ -770,14 +770,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 09b4f19f100fe82a8321b9ded99e679b7eedc1fa -R 4660953738e09e48658e726d4ab4929b +P 5a32bfc17ed022c85d2615c34b41a3dcae2594bd +R 40ba71f59fe4e9d89ef2ec58e5f61b4f U drh -Z eb38c72c7392595b8c9af9da37273b2d +Z 900447894e5e2bfd8a391e7b7ee91c4f -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFK+rlYoxKgR168RlERAkd5AJ0ZWUnPqChJybXaCT0e1e2vLdOf+ACePwEx -ifVUs5BZPo6twb6xD420UW4= -=eW+2 +iD8DBQFK+yROoxKgR168RlERAgxxAKCHj71qH3RTTKkacqnNolY2rfQh3ACfYfTz +I5+1whsNXmr3GYydKvNnoeA= +=f867 -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 00cbd83489..b8542ab814 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5a32bfc17ed022c85d2615c34b41a3dcae2594bd \ No newline at end of file +5a474a867c5988ad5ec03719516fdd38f0da5c2c \ No newline at end of file diff --git a/src/func.c b/src/func.c index 980d04edb6..e1ad9a36cc 100644 --- a/src/func.c +++ b/src/func.c @@ -177,6 +177,7 @@ static void substrFunc( return; } p0type = sqlite3_value_type(argv[0]); + p1 = sqlite3_value_int(argv[1]); if( p0type==SQLITE_BLOB ){ len = sqlite3_value_bytes(argv[0]); z = sqlite3_value_blob(argv[0]); @@ -186,11 +187,12 @@ static void substrFunc( z = sqlite3_value_text(argv[0]); if( z==0 ) return; len = 0; - for(z2=z; *z2; len++){ - SQLITE_SKIP_UTF8(z2); + if( p1<0 ){ + for(z2=z; *z2; len++){ + SQLITE_SKIP_UTF8(z2); + } } } - p1 = sqlite3_value_int(argv[1]); if( argc==3 ){ p2 = sqlite3_value_int(argv[2]); if( p2<0 ){ @@ -220,10 +222,6 @@ static void substrFunc( } } assert( p1>=0 && p2>=0 ); - if( p1+p2>len ){ - p2 = len-p1; - if( p2<0 ) p2 = 0; - } if( p0type!=SQLITE_BLOB ){ while( *z && p1 ){ SQLITE_SKIP_UTF8(z); @@ -234,6 +232,10 @@ static void substrFunc( } sqlite3_result_text(context, (char*)z, (int)(z2-z), SQLITE_TRANSIENT); }else{ + if( p1+p2>len ){ + p2 = len-p1; + if( p2<0 ) p2 = 0; + } sqlite3_result_blob(context, (char*)&z[p1], (int)p2, SQLITE_TRANSIENT); } } -- 2.47.3