Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | 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) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
263a8ca40f7ff66fbdcb43bf9032391d |
User & Date: | drh 2002-11-11 00:05:43.000 |
Context
2002-11-11
| ||
01:04 | Back out the changes in the pager that sorted pages prior to writing them to the database. Additional measurements showed no performance gains. (CVS 785) (check-in: 745d66395d user: drh tags: trunk) | |
00:05 | 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) (check-in: 263a8ca40f user: drh tags: trunk) | |
2002-11-10
| ||
23:32 | Two optimizations to the pager: (1) Write dirty pages back to the database file in order and (2) Keep a separate list of in-memory pages that are in the checkpoint journal in order to speed a checkpoint commit. (CVS 783) (check-in: a6ef6657a4 user: drh tags: trunk) | |
Changes
Changes to src/vdbe.c.
︙ | ︙ | |||
32 33 34 35 36 37 38 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** 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.184 2002/11/11 00:05:43 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** The makefile scans this source file and creates the following ** array of string constants which are the names of all VDBE opcodes. |
︙ | ︙ | |||
829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 | */ #define Release(P,I) if((P)->aStack[I].flags&STK_Dyn){ hardRelease(P,I); } static void hardRelease(Vdbe *p, int i){ sqliteFree(p->zStack[i]); p->zStack[i] = 0; p->aStack[i].flags &= ~(STK_Str|STK_Dyn|STK_Static|STK_Ephem); } /* ** Convert the given stack entity into a integer if it isn't one ** already. ** ** Any prior string or real representation is invalidated. ** NULLs are converted into 0. */ #define Integerify(P,I) \ if(((P)->aStack[(I)].flags&STK_Int)==0){ hardIntegerify(P,I); } static void hardIntegerify(Vdbe *p, int i){ if( p->aStack[i].flags & STK_Real ){ p->aStack[i].i = (int)p->aStack[i].r; Release(p, i); }else if( p->aStack[i].flags & STK_Str ){ | > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 | */ #define Release(P,I) if((P)->aStack[I].flags&STK_Dyn){ hardRelease(P,I); } static void hardRelease(Vdbe *p, int i){ sqliteFree(p->zStack[i]); p->zStack[i] = 0; 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. ** ** Any prior string or real representation is invalidated. ** NULLs are converted into 0. */ #define Integerify(P,I) \ if(((P)->aStack[(I)].flags&STK_Int)==0){ hardIntegerify(P,I); } static void hardIntegerify(Vdbe *p, int i){ if( p->aStack[i].flags & STK_Real ){ p->aStack[i].i = (int)p->aStack[i].r; Release(p, i); }else if( p->aStack[i].flags & STK_Str ){ toInt(p->zStack[i], &p->aStack[i].i); Release(p, i); }else{ p->aStack[i].i = 0; } p->aStack[i].flags = STK_Int; } |
︙ | ︙ | |||
963 964 965 966 967 968 969 | zNum++; if( *zNum=='-' || *zNum=='+' ) zNum++; if( !isdigit(*zNum) ) return 0; while( isdigit(*zNum) ) zNum++; return *zNum==0; } | < < < < < < < < < | 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 | zNum++; if( *zNum=='-' || *zNum=='+' ) zNum++; if( !isdigit(*zNum) ) return 0; while( isdigit(*zNum) ) zNum++; return *zNum==0; } /* ** Delete a keylist */ static void KeylistFree(Keylist *p){ while( p ){ Keylist *pNext = p->pNext; sqliteFree(p); |
︙ | ︙ | |||
2105 2106 2107 2108 2109 2110 2111 | int i = aStack[tos].r; double r = i; if( r!=aStack[tos].r ){ goto mismatch; } aStack[tos].i = i; }else if( aStack[tos].flags & STK_Str ){ | > | | | 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 | int i = aStack[tos].r; double r = i; if( r!=aStack[tos].r ){ goto mismatch; } aStack[tos].i = i; }else if( aStack[tos].flags & STK_Str ){ int v; if( !toInt(zStack[tos], &v) ){ goto mismatch; } p->aStack[tos].i = v; }else{ goto mismatch; } Release(p, tos); p->aStack[tos].flags = STK_Int; break; |
︙ | ︙ | |||
2246 2247 2248 2249 2250 2251 2252 | case OP_Ne: case OP_Lt: case OP_Le: case OP_Gt: case OP_Ge: { int tos = p->tos; int nos = tos - 1; | | | | > > | | > > | 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 | case OP_Ne: case OP_Lt: case OP_Le: case OP_Gt: case OP_Ge: { int tos = p->tos; int nos = tos - 1; int c, v; int ft, fn; VERIFY( if( nos<0 ) goto not_enough_stack; ) ft = aStack[tos].flags; fn = aStack[nos].flags; if( (ft | fn) & STK_Null ){ POPSTACK; POPSTACK; if( pOp->p2 ){ if( pOp->p1 ) pc = pOp->p2-1; }else{ p->tos++; aStack[nos].flags = STK_Null; } 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 && 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 && 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; c = sqliteCompare(zStack[nos], zStack[tos]); } switch( pOp->opcode ){ case OP_Eq: c = c==0; break; |
︙ | ︙ | |||
4270 4271 4272 4273 4274 4275 4276 | VERIFY( if( iSet<0 || iSet>=p->nSet ) goto bad_instruction; ) VERIFY( if( NeedStack(p, p->tos) ) goto no_mem; ) pSet = &p->aSet[iSet]; nRoot = sqliteHashCount(&pSet->hash); aRoot = sqliteMalloc( sizeof(int)*(nRoot+1) ); for(j=0, i=sqliteHashFirst(&pSet->hash); i; i=sqliteHashNext(i), j++){ | | | 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 | VERIFY( if( iSet<0 || iSet>=p->nSet ) goto bad_instruction; ) VERIFY( if( NeedStack(p, p->tos) ) goto no_mem; ) pSet = &p->aSet[iSet]; nRoot = sqliteHashCount(&pSet->hash); aRoot = sqliteMalloc( sizeof(int)*(nRoot+1) ); for(j=0, i=sqliteHashFirst(&pSet->hash); i; i=sqliteHashNext(i), j++){ toInt((char*)sqliteHashKey(i), &aRoot[j]); } aRoot[j] = 0; z = sqliteBtreeIntegrityCheck(pOp->p2 ? db->pBeTemp : pBt, aRoot, nRoot); if( z==0 || z[0]==0 ){ if( z ) sqliteFree(z); zStack[tos] = "ok"; aStack[tos].n = 3; |
︙ | ︙ |