From 41692e9d7c4eca48bb3ed00a7bdea9a97fbbb016 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 25 Jan 2011 04:34:51 +0000 Subject: [PATCH] Shave a few cycles so that performance is better than 3.7.4 in speed tests. FossilOrigin-Name: e14649301138b6840e24a4bbd2cf5205c0f72409 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/btree.c | 7 +------ src/pcache1.c | 42 ++++++++++++++++++++++++++++++++++-------- 4 files changed, 46 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index 86f9717d50..82264d4976 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Modify\sthe\stest_quote.c\sdemonstration\sshim\sso\sthat\sit\sworks\swhen\nSQLITE_THREADSAFE=0\sis\sdefined. -D 2011-01-24T20:18:05.760 +C Shave\sa\sfew\scycles\sso\sthat\sperformance\sis\sbetter\sthan\s3.7.4\sin\sspeed\stests. +D 2011-01-25T04:34:51.468 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in de6498556d536ae60bb8bb10e8c1ba011448658c F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -122,7 +122,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 8c39a1ebba1e9dc385519cc4d434c7b0cab6638c F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef F src/btmutex.c 96a12f50f7a17475155971a241d85ec5171573ff -F src/btree.c a27c3b41082889fc258278ba501ff2594dda2a41 +F src/btree.c 9004c98fc576306eee4fc0562ffeb362ef53912c F src/btree.h 10f9296bf4edf034f5adce921b7b4383a56a1c90 F src/btreeInt.h 20f73dc93b1eeb83afd7259fbc6bd7dcf2df7fe4 F src/build.c 00a327120d81ace6267e714ae8010c997d55de5d @@ -170,7 +170,7 @@ F src/pager.h 0ea59db2a33bc6c2c02cae34de33367e1effdf76 F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 F src/pcache.c 09d38c44ab275db581f7a2f6ff8b9bc7f8c0faaa F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050 -F src/pcache1.c 2610bcebf127df5ff82730c0c130cb35d4d6debe +F src/pcache1.c 54401ef4ea296b5bc2950bfbf5e68d6e931ab676 F src/pragma.c 8a6cd3c787f882fa44f6490d2411fc26839ce8f3 F src/prepare.c c8b877b80721d70b68053fd9ae30ec6d63eeeadc F src/printf.c df2ff3bb5409e8958136933342c46464fbd017e7 @@ -900,14 +900,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 8d1065411aadf189880606c48ab63dd2a56b9793 -R 0d85535bc15a93b18012673a71c32db9 +P b70bcccaf5597c8a59cccb64fb997523f7b8fe4f +R db20a3af8ef33b3a30d380bbda0431c6 U drh -Z 70d633de5e7a3d8ed3285ad89550ec3c +Z 4ead49fabdd8a6e774c2367e68e73ca5 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNPd6AoxKgR168RlERAv1EAJsHL7T752myN3OrKk+lrXEgPoRywwCffQlq -RmLBh/72A/WvCFzCC21cc98= -=oeId +iD8DBQFNPlLvoxKgR168RlERApslAJ9T2ytfJxLqucALSfvcNNpr6129cACfegvL +qPLVUx7DCZ7ypVE082HOjX8= +=7+yb -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index bb0e5367b4..81467c911d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b70bcccaf5597c8a59cccb64fb997523f7b8fe4f \ No newline at end of file +e14649301138b6840e24a4bbd2cf5205c0f72409 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index bec19e315f..aa120159de 100644 --- a/src/btree.c +++ b/src/btree.c @@ -918,14 +918,9 @@ static void btreeParseCellPtr( /* This is the (easy) common case where the entire payload fits ** on the local page. No overflow is required. */ - int nSize; /* Total size of cell content in bytes */ - nSize = nPayload + n; + if( (pInfo->nSize = (u16)(n+nPayload))<4 ) pInfo->nSize = 4; pInfo->nLocal = (u16)nPayload; pInfo->iOverflow = 0; - if( (nSize & ~3)==0 ){ - nSize = 4; /* Minimum cell size is 4 */ - } - pInfo->nSize = (u16)nSize; }else{ /* If the payload will not fit completely on the local page, we have ** to decide how much to store locally and how much to spill onto diff --git a/src/pcache1.c b/src/pcache1.c index 4af41407f9..50765a2fac 100644 --- a/src/pcache1.c +++ b/src/pcache1.c @@ -50,6 +50,7 @@ struct PGroup { sqlite3_mutex *mutex; /* MUTEX_STATIC_LRU or NULL */ int nMaxPage; /* Sum of nMax for purgeable caches */ int nMinPage; /* Sum of nMin for purgeable caches */ + int mxPinned; /* nMaxpage + 10 - nMinPage */ int nCurrentPage; /* Number of purgeable pages allocated */ PgHdr1 *pLruHead, *pLruTail; /* LRU list of unpinned pages */ }; @@ -73,6 +74,7 @@ struct PCache1 { int bPurgeable; /* True if cache is purgeable */ unsigned int nMin; /* Minimum number of pages reserved */ unsigned int nMax; /* Configured "cache_size" value */ + unsigned int mxPinned; /* nMax*9/10 */ /* Hash table of all pages. The following variables may only be accessed ** when the accessor is holding the PGroup mutex. @@ -516,6 +518,7 @@ static int pcache1Init(void *NotUsed){ pcache1.grp.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU); pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_PMEM); } + pcache1.grp.mxPinned = 10; pcache1.isInit = 1; return SQLITE_OK; } @@ -565,6 +568,7 @@ static sqlite3_pcache *pcache1Create(int szPage, int bPurgeable){ memset(pCache, 0, sz); if( separateCache ){ pGroup = (PGroup*)&pCache[1]; + pGroup->mxPinned = 10; }else{ pGroup = &pcache1_g.grp; } @@ -575,6 +579,7 @@ static sqlite3_pcache *pcache1Create(int szPage, int bPurgeable){ pCache->nMin = 10; pcache1EnterMutex(pGroup); pGroup->nMinPage += pCache->nMin; + pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; pcache1LeaveMutex(pGroup); } } @@ -592,7 +597,9 @@ static void pcache1Cachesize(sqlite3_pcache *p, int nMax){ PGroup *pGroup = pCache->pGroup; pcache1EnterMutex(pGroup); pGroup->nMaxPage += (nMax - pCache->nMax); + pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; pCache->nMax = nMax; + pCache->mxPinned = nMax*9/10; pcache1EnforceMaxPage(pGroup); pcache1LeaveMutex(pGroup); } @@ -667,12 +674,14 @@ static int pcache1Pagecount(sqlite3_pcache *p){ static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){ unsigned int nPinned; PCache1 *pCache = (PCache1 *)p; - PGroup *pGroup = pCache->pGroup; + PGroup *pGroup; PgHdr1 *pPage = 0; assert( pCache->bPurgeable || createFlag!=1 ); - pcache1EnterMutex(pGroup); - if( createFlag==1 ) sqlite3BeginBenignMalloc(); + assert( pCache->bPurgeable || pCache->nMin==0 ); + assert( pCache->bPurgeable==0 || pCache->nMin==10 ); + assert( pCache->nMin==0 || pCache->bPurgeable ); + pcache1EnterMutex(pGroup = pCache->pGroup); /* Step 1: Search the hash table for an existing entry. */ if( pCache->nHash>0 ){ @@ -686,11 +695,25 @@ static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){ goto fetch_out; } + /* The pGroup local variable will normally be initialized by the + ** pcache1EnterMutex() macro above. But if SQLITE_MUTEX_OMIT is defined, + ** then pcache1EnterMutex() is a no-op, so we have to initialize the + ** local variable here. Delaying the initialization of pGroup is an + ** optimization: The common case is to exit the module before reaching + ** this point. + */ +#ifdef SQLITE_MUTEX_OMIT + pGroup = pCache->pGroup; +#endif + + /* Step 3: Abort if createFlag is 1 but the cache is nearly full */ nPinned = pCache->nPage - pCache->nRecyclable; + assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage ); + assert( pCache->mxPinned == pCache->nMax*9/10 ); if( createFlag==1 && ( - nPinned>=(pGroup->nMaxPage+pCache->nMin-pGroup->nMinPage) - || nPinned>=(pCache->nMax * 9 / 10) + nPinned>=pGroup->mxPinned + || nPinned>=pCache->mxPinned || pcache1UnderMemoryPressure(pCache) )){ goto fetch_out; @@ -706,15 +729,16 @@ static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){ || pGroup->nCurrentPage>=pGroup->nMaxPage || pcache1UnderMemoryPressure(pCache) )){ + PCache1 *pOtherCache; pPage = pGroup->pLruTail; pcache1RemoveFromHash(pPage); pcache1PinPage(pPage); - if( pPage->pCache->szPage!=pCache->szPage ){ + if( (pOtherCache = pPage->pCache)->szPage!=pCache->szPage ){ pcache1FreePage(pPage); pPage = 0; }else{ pGroup->nCurrentPage -= - (pPage->pCache->bPurgeable - pCache->bPurgeable); + (pOtherCache->bPurgeable - pCache->bPurgeable); } } @@ -722,9 +746,11 @@ static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){ ** attempt to allocate a new one. */ if( !pPage ){ + if( createFlag==1 ) sqlite3BeginBenignMalloc(); pcache1LeaveMutex(pGroup); pPage = pcache1AllocPage(pCache); pcache1EnterMutex(pGroup); + if( createFlag==1 ) sqlite3EndBenignMalloc(); } if( pPage ){ @@ -743,7 +769,6 @@ fetch_out: if( pPage && iKey>pCache->iMaxKey ){ pCache->iMaxKey = iKey; } - if( createFlag==1 ) sqlite3EndBenignMalloc(); pcache1LeaveMutex(pGroup); return (pPage ? PGHDR1_TO_PAGE(pPage) : 0); } @@ -853,6 +878,7 @@ static void pcache1Destroy(sqlite3_pcache *p){ pcache1TruncateUnsafe(pCache, 0); pGroup->nMaxPage -= pCache->nMax; pGroup->nMinPage -= pCache->nMin; + pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; pcache1EnforceMaxPage(pGroup); pcache1LeaveMutex(pGroup); sqlite3_free(pCache->apHash);