From 59bf00cb54fa87425444013fb732f68be69f71a1 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 8 Dec 2013 23:33:28 +0000 Subject: [PATCH] Another simplification to the OP_MakeRecord opcode, making it slightly faster and very slightly smaller. FossilOrigin-Name: f2f5a3ce9d075c4b1ac586c5db3a623d9035402d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 29 +++++++++++++++++++---------- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 19fb8c1241..65c6431388 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunnecessary\scalls\sto\ssqlite3VarintLen()\sfrom\sthe\sOP_MakeRecord\sopcode. -D 2013-12-08T22:59:29.482 +C Another\ssimplification\sto\sthe\sOP_MakeRecord\sopcode,\smaking\sit\sslightly\nfaster\sand\svery\sslightly\ssmaller. +D 2013-12-08T23:33:28.824 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,7 +280,7 @@ F src/update.c d1c2477dcf14d90999d1935af4efb4806553250b F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 76ed0519296e3f62e97e57dab1999e34184c8e49 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 7f51e9d422aefe6bcbaf7bf680e0d4ca9f6288cb +F src/vdbe.c 6ccb107de55a34b7676a9eaa0aeb827015723fa4 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h 05fbda0e061dbc4aaa2709a8cccf3515c245b263 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P fbcc1a3ebb016225c3580181c908a2904cc184a5 -R 09b58c480760cc431d5e01573bf9e4b3 +P 7a234fc3c5e7970ffe0b8d6ac33c26acb64b5c4d +R 57ac1272f14efea499bd7c6c07bb251b U drh -Z 1bf421a053293bdaa5254a0efb062c9a +Z f1f04177179428a44e2d9de7658a5211 diff --git a/manifest.uuid b/manifest.uuid index d22393ad7f..2faf99014f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7a234fc3c5e7970ffe0b8d6ac33c26acb64b5c4d \ No newline at end of file +f2f5a3ce9d075c4b1ac586c5db3a623d9035402d \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index b0b56c4567..5133591e3c 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2560,7 +2560,8 @@ case OP_MakeRecord: { int nField; /* Number of fields in the record */ char *zAffinity; /* The affinity string for the record */ int file_format; /* File format to use for encoding */ - int i; /* Space used in zNewRecord[] */ + int i; /* Space used in zNewRecord[] header */ + int j; /* Space used in zNewRecord[] content */ int len; /* Length of a field */ /* Assuming the record contains N fields, the record format looks @@ -2597,17 +2598,21 @@ case OP_MakeRecord: { /* Loop through the elements that will make up the record to figure ** out how much space is required for the new record. */ - for(pRec=pData0; pRec<=pLast; pRec++){ + assert( pData0<=pLast ); + pRec = pData0; + do{ assert( memIsValid(pRec) ); if( zAffinity ){ applyAffinity(pRec, zAffinity[pRec-pData0], encoding); } - if( pRec->flags&MEM_Zero && pRec->n>0 ){ + if( (pRec->flags&MEM_Zero)!=0 && pRec->n>0 ){ sqlite3VdbeMemExpandBlob(pRec); } serial_type = sqlite3VdbeSerialType(pRec, file_format); len = sqlite3VdbeSerialTypeLen(serial_type); nData += len; + testcase( serial_type==127 ); + testcase( serial_type==128 ); nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type); if( pRec->flags & MEM_Zero ){ /* Only pure zero-filled BLOBs can be input to this Opcode. @@ -2616,9 +2621,11 @@ case OP_MakeRecord: { }else if( len ){ nZero = 0; } - } + }while( (++pRec)<=pLast ); /* Add the initial header varint and total the size */ + testcase( nHdr==126 ); + testcase( nHdr==127 ); if( nHdr<=126 ){ /* The common case */ nHdr += 1; @@ -2645,14 +2652,16 @@ case OP_MakeRecord: { /* Write the record */ i = putVarint32(zNewRecord, nHdr); - for(pRec=pData0; pRec<=pLast; pRec++){ + j = nHdr; + assert( pData0<=pLast ); + pRec = pData0; + do{ serial_type = sqlite3VdbeSerialType(pRec, file_format); i += putVarint32(&zNewRecord[i], serial_type); /* serial type */ - } - for(pRec=pData0; pRec<=pLast; pRec++){ /* serial data */ - i += sqlite3VdbeSerialPut(&zNewRecord[i], (int)(nByte-i), pRec,file_format); - } - assert( i==nByte ); + j += sqlite3VdbeSerialPut(&zNewRecord[j], (int)(nByte-j), pRec,file_format); + }while( (++pRec)<=pLast ); + assert( i==nHdr ); + assert( j==nByte ); assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); pOut->n = (int)nByte;