From 32c05e993f33e216391ffda0b56b8996556192a0 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 11 Nov 2002 00:05:42 +0000 Subject: [PATCH] Replace the atoi() library routine with a faster home-grown version in the VDBE. This gives a dramatic speed improvement for some kinds of queries. (CVS 784) FossilOrigin-Name: 263a8ca40f7ff66fbdcb43bf9032391d5b1e68bd --- manifest | 12 +++++----- manifest.uuid | 2 +- src/vdbe.c | 61 +++++++++++++++++++++++++++++++++++---------------- 3 files changed, 49 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index b0e3068ebe..c484e547a3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Two\soptimizations\sto\sthe\spager:\s(1)\sWrite\sdirty\spages\sback\sto\sthe\sdatabase\nfile\sin\sorder\sand\s(2)\sKeep\sa\sseparate\slist\sof\sin-memory\spages\sthat\sare\sin\nthe\scheckpoint\sjournal\sin\sorder\sto\sspeed\sa\scheckpoint\scommit.\s(CVS\s783) -D 2002-11-10T23:32:57 +C Replace\sthe\satoi()\slibrary\sroutine\swith\sa\sfaster\shome-grown\sversion\sin\sthe\nVDBE.\s\sThis\sgives\sa\sdramatic\sspeed\simprovement\sfor\ssome\skinds\sof\squeries.\s(CVS\s784) +D 2002-11-11T00:05:43 F Makefile.in d6c9a85c2a5e696843201d090dcf8bf2f8716f2a F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -52,7 +52,7 @@ F src/tokenize.c 75e3bb37305b64e118e709752066f494c4f93c30 F src/trigger.c 5ba917fc226b96065108da28186c2efaec53e481 F src/update.c 881e4c8e7c786545da4fd2d95da19252b2e31137 F src/util.c ca7650ef2cc2d50241e48029fca109a3016144ee -F src/vdbe.c a187467bc4e9ef7793969b5010d7297341b19394 +F src/vdbe.c 7d46f087c1da55ba9be38f70d92a03c52c8a2ccb F src/vdbe.h b7584044223104ba7896a7f87b66daebdd6022ba F src/where.c 615a0f0bed305bcb27073c69347ea75018e8b58d F test/all.test efd958d048c70a3247997c482f0b33561f7759f0 @@ -149,7 +149,7 @@ F www/speed.tcl a20a792738475b68756ea7a19321600f23d1d803 F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218 -P a29d60ecc5ee3f535142a81f56eecbef7875ef22 -R 52d1e18697b72d70d44fdac37bed7445 +P a6ef6657a4377684dc2fce7be2bbf009fd2d2f37 +R 185b0bc33f10b4a768e6cfb7280605c4 U drh -Z 7623b80b72f443af5ce24d861a13e847 +Z f3f9009eb197efb6353cb5684648e29d diff --git a/manifest.uuid b/manifest.uuid index cb446ee9a4..b12c1575b0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a6ef6657a4377684dc2fce7be2bbf009fd2d2f37 \ No newline at end of file +263a8ca40f7ff66fbdcb43bf9032391d5b1e68bd \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index f5c5ca02bb..d80c3c0a5c 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -36,7 +36,7 @@ ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.183 2002/11/01 01:55:38 drh Exp $ +** $Id: vdbe.c,v 1.184 2002/11/11 00:05:43 drh Exp $ */ #include "sqliteInt.h" #include @@ -834,6 +834,33 @@ static void hardRelease(Vdbe *p, int i){ p->aStack[i].flags &= ~(STK_Str|STK_Dyn|STK_Static|STK_Ephem); } +/* +** Return TRUE if zNum is an integer and write +** the value of the integer into *pNum. +** +** Under Linux (RedHat 7.2) this routine is much faster than atoi() +** for converting strings into integers. +*/ +static int toInt(const char *zNum, int *pNum){ + int v = 0; + int neg; + if( *zNum=='-' ){ + neg = 1; + zNum++; + }else if( *zNum=='+' ){ + neg = 0; + zNum++; + }else{ + neg = 0; + } + while( isdigit(*zNum) ){ + v = v*10 + *zNum - '0'; + zNum++; + } + *pNum = neg ? -v : v; + return *zNum==0; +} + /* ** Convert the given stack entity into a integer if it isn't one ** already. @@ -848,7 +875,7 @@ static void hardIntegerify(Vdbe *p, int i){ p->aStack[i].i = (int)p->aStack[i].r; Release(p, i); }else if( p->aStack[i].flags & STK_Str ){ - p->aStack[i].i = atoi(p->zStack[i]); + toInt(p->zStack[i], &p->aStack[i].i); Release(p, i); }else{ p->aStack[i].i = 0; @@ -967,15 +994,6 @@ static int isNumber(const char *zNum){ return *zNum==0; } -/* -** Return TRUE if zNum is an integer. -*/ -static int isInteger(const char *zNum){ - if( *zNum=='-' || *zNum=='+' ) zNum++; - while( isdigit(*zNum) ) zNum++; - return *zNum==0; -} - /* ** Delete a keylist */ @@ -2109,10 +2127,11 @@ case OP_MustBeInt: { } aStack[tos].i = i; }else if( aStack[tos].flags & STK_Str ){ - if( !isInteger(zStack[tos]) ){ + int v; + if( !toInt(zStack[tos], &v) ){ goto mismatch; } - p->aStack[tos].i = atoi(p->zStack[tos]); + p->aStack[tos].i = v; }else{ goto mismatch; } @@ -2250,7 +2269,7 @@ case OP_Gt: case OP_Ge: { int tos = p->tos; int nos = tos - 1; - int c; + int c, v; int ft, fn; VERIFY( if( nos<0 ) goto not_enough_stack; ) ft = aStack[tos].flags; @@ -2267,11 +2286,15 @@ case OP_Ge: { break; }else if( (ft & fn & STK_Int)==STK_Int ){ c = aStack[nos].i - aStack[tos].i; - }else if( (ft & STK_Int)!=0 && (fn & STK_Str)!=0 && isInteger(zStack[nos]) ){ - Integerify(p, nos); + }else if( (ft & STK_Int)!=0 && (fn & STK_Str)!=0 && toInt(zStack[nos],&v) ){ + Release(p, nos); + aStack[nos].i = v; + aStack[nos].flags = STK_Int; c = aStack[nos].i - aStack[tos].i; - }else if( (fn & STK_Int)!=0 && (ft & STK_Str)!=0 && isInteger(zStack[tos]) ){ - Integerify(p, tos); + }else if( (fn & STK_Int)!=0 && (ft & STK_Str)!=0 && toInt(zStack[tos],&v) ){ + Release(p, tos); + aStack[tos].i = v; + aStack[tos].flags = STK_Int; c = aStack[nos].i - aStack[tos].i; }else{ if( Stringify(p, tos) || Stringify(p, nos) ) goto no_mem; @@ -4274,7 +4297,7 @@ case OP_IntegrityCk: { nRoot = sqliteHashCount(&pSet->hash); aRoot = sqliteMalloc( sizeof(int)*(nRoot+1) ); for(j=0, i=sqliteHashFirst(&pSet->hash); i; i=sqliteHashNext(i), j++){ - aRoot[j] = atoi((char*)sqliteHashKey(i)); + toInt((char*)sqliteHashKey(i), &aRoot[j]); } aRoot[j] = 0; z = sqliteBtreeIntegrityCheck(pOp->p2 ? db->pBeTemp : pBt, aRoot, nRoot); -- 2.47.3