1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-09-02 12:21:26 +03:00

Get the sqlite3VdbeSerialGet() routine to run faster by avoiding the use

of local variables.

FossilOrigin-Name: 8267d82174099e548a4f78d06af0c6324c89b83d
This commit is contained in:
drh
2014-08-22 14:34:05 +00:00
parent 3f5b199eb5
commit 14a924a5cd
4 changed files with 73 additions and 47 deletions

View File

@@ -1,5 +1,5 @@
C Change\sa\swhile-loop\sinto\sa\sdo-loop\sin\ssqlite3VdbeSerialPut()\sfor\sa\ssmall\nsize\sreduction\sand\sperformance\simprovement. C Get\sthe\ssqlite3VdbeSerialGet()\sroutine\sto\srun\sfaster\sby\savoiding\sthe\suse\nof\slocal\svariables.
D 2014-08-22T13:22:32.819 D 2014-08-22T14:34:05.936
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308 F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -228,7 +228,7 @@ F src/shell.c 728d2226594d356bf4fbdbdfd08538fd78fd06f3
F src/sqlite.h.in ed9d35990c61f0388ca6405706455c4095310553 F src/sqlite.h.in ed9d35990c61f0388ca6405706455c4095310553
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
F src/sqliteInt.h 641f8fbb65ca2084c8df95b525f6f82c7a1e91ae F src/sqliteInt.h 99bd20e5a12dce7ba290e938123d27e87b5eae27
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -288,7 +288,7 @@ F src/vdbe.c f7f4066e4d6e3858878d76ce9288ea603e12ddf6
F src/vdbe.h c63fad052c9e7388d551e556e119c0bcf6bebdf8 F src/vdbe.h c63fad052c9e7388d551e556e119c0bcf6bebdf8
F src/vdbeInt.h f5513f2b5ac1e2c5128996c7ea23add256a301df F src/vdbeInt.h f5513f2b5ac1e2c5128996c7ea23add256a301df
F src/vdbeapi.c 7858d7e7cd23267d3fbca18e3a28cce8e0d162a8 F src/vdbeapi.c 7858d7e7cd23267d3fbca18e3a28cce8e0d162a8
F src/vdbeaux.c 9c9571706aaf0e5debab5b01629ef569cde40920 F src/vdbeaux.c f83d5c265aea19d2e49ba018beaf99acff934020
F src/vdbeblob.c 9205ce9d3b064d9600f8418a897fc88b5687d9ac F src/vdbeblob.c 9205ce9d3b064d9600f8418a897fc88b5687d9ac
F src/vdbemem.c d90a1e8acf8b63dc9d14cbbea12bfec6cec31394 F src/vdbemem.c d90a1e8acf8b63dc9d14cbbea12bfec6cec31394
F src/vdbesort.c f7f5563bf7d4695ca8f3203f3bf9de96d04ed0b3 F src/vdbesort.c f7f5563bf7d4695ca8f3203f3bf9de96d04ed0b3
@@ -1188,7 +1188,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 369c480cda6fa66394b995346bbf51f3298446e1 P 750bb0a0960606ab24037e0992e9f7a17524cc3e
R 9c1a6f648ddd3ddf03093ccb99facf2b R 6bc6a7681a89a137c23142249db6cf86
T *branch * experimental
T *sym-experimental *
T -sym-trunk *
U drh U drh
Z 453b7d6a328e84b291043b75c1b3327d Z 612ca7a9b67c6d8d8dbe2b7affb6d3eb

View File

@@ -1 +1 @@
750bb0a0960606ab24037e0992e9f7a17524cc3e 8267d82174099e548a4f78d06af0c6324c89b83d

View File

@@ -153,6 +153,18 @@
# define SQLITE_PTR_TO_INT(X) ((int)(X)) # define SQLITE_PTR_TO_INT(X) ((int)(X))
#endif #endif
/*
** A macro to hint to the compiler that a function should not be
** inlined.
*/
#if defined(__GNUC__)
# define SQLITE_NOINLINE __attribute__((noinline))
#elif defined(_MSC_VER)
# define SQLITE_NOINLINE __declspec(noinline)
#else
# define SQLITE_NOINLINE
#endif
/* /*
** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2. ** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2.
** 0 means mutexes are permanently disable and the library is never ** 0 means mutexes are permanently disable and the library is never

View File

@@ -2965,14 +2965,55 @@ u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){
/* /*
** Deserialize the data blob pointed to by buf as serial type serial_type ** Deserialize the data blob pointed to by buf as serial type serial_type
** and store the result in pMem. Return the number of bytes read. ** and store the result in pMem. Return the number of bytes read.
**
** This function is implemented as two separate routines for performance.
** The few cases that require local variables are broken out into a separate
** routine so that in most cases the overhead of moving the stack pointer
** is avoided.
*/ */
u32 sqlite3VdbeSerialGet( static u32 SQLITE_NOINLINE serialGet(
const unsigned char *buf, /* Buffer to deserialize from */ const unsigned char *buf, /* Buffer to deserialize from */
u32 serial_type, /* Serial type to deserialize */ u32 serial_type, /* Serial type to deserialize */
Mem *pMem /* Memory cell to write value into */ Mem *pMem /* Memory cell to write value into */
){ ){
u64 x; u64 x;
u32 y; u32 y = FOUR_BYTE_UINT(buf);
if( serial_type==4 ){
pMem->u.i = (i64)*(int*)&y;
pMem->flags = MEM_Int;
testcase( pMem->u.i<0 );
return 4;
}
x = (((u64)y)<<32)|FOUR_BYTE_UINT(buf+4);
if( serial_type==6 ){
pMem->u.i = *(i64*)&x;
pMem->flags = MEM_Int;
testcase( pMem->u.i<0 );
}else{
#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT)
/* Verify that integers and floating point values use the same
** byte order. Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is
** defined that 64-bit floating point values really are mixed
** endian.
*/
static const u64 t1 = ((u64)0x3ff00000)<<32;
static const double r1 = 1.0;
u64 t2 = t1;
swapMixedEndianFloat(t2);
assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 );
#endif
assert( sizeof(x)==8 && sizeof(pMem->r)==8 );
swapMixedEndianFloat(x);
memcpy(&pMem->r, &x, sizeof(x));
pMem->flags = sqlite3IsNaN(pMem->r) ? MEM_Null : MEM_Real;
}
return 8;
}
u32 sqlite3VdbeSerialGet(
const unsigned char *buf, /* Buffer to deserialize from */
u32 serial_type, /* Serial type to deserialize */
Mem *pMem /* Memory cell to write value into */
){
switch( serial_type ){ switch( serial_type ){
case 10: /* Reserved for future use */ case 10: /* Reserved for future use */
case 11: /* Reserved for future use */ case 11: /* Reserved for future use */
@@ -2998,47 +3039,19 @@ u32 sqlite3VdbeSerialGet(
testcase( pMem->u.i<0 ); testcase( pMem->u.i<0 );
return 3; return 3;
} }
case 4: { /* 4-byte signed integer */
y = FOUR_BYTE_UINT(buf);
pMem->u.i = (i64)*(int*)&y;
pMem->flags = MEM_Int;
testcase( pMem->u.i<0 );
return 4;
}
case 5: { /* 6-byte signed integer */ case 5: { /* 6-byte signed integer */
pMem->u.i = FOUR_BYTE_UINT(buf+2) + (((i64)1)<<32)*TWO_BYTE_INT(buf); pMem->u.i = FOUR_BYTE_UINT(buf+2) + (((i64)1)<<32)*TWO_BYTE_INT(buf);
pMem->flags = MEM_Int; pMem->flags = MEM_Int;
testcase( pMem->u.i<0 ); testcase( pMem->u.i<0 );
return 6; return 6;
} }
case 4: /* 4-byte signed integer */
case 6: /* 8-byte signed integer */ case 6: /* 8-byte signed integer */
case 7: { /* IEEE floating point */ case 7: { /* IEEE floating point */
#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT) /* These three cases require local variables, so do them in a
/* Verify that integers and floating point values use the same ** separate routine to avoid having to move the frame pointer in
** byte order. Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is ** the common case */
** defined that 64-bit floating point values really are mixed return serialGet(buf,serial_type,pMem);
** endian.
*/
static const u64 t1 = ((u64)0x3ff00000)<<32;
static const double r1 = 1.0;
u64 t2 = t1;
swapMixedEndianFloat(t2);
assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 );
#endif
x = FOUR_BYTE_UINT(buf);
y = FOUR_BYTE_UINT(buf+4);
x = (x<<32) | y;
if( serial_type==6 ){
pMem->u.i = *(i64*)&x;
pMem->flags = MEM_Int;
testcase( pMem->u.i<0 );
}else{
assert( sizeof(x)==8 && sizeof(pMem->r)==8 );
swapMixedEndianFloat(x);
memcpy(&pMem->r, &x, sizeof(x));
pMem->flags = sqlite3IsNaN(pMem->r) ? MEM_Null : MEM_Real;
}
return 8;
} }
case 8: /* Integer 0 */ case 8: /* Integer 0 */
case 9: { /* Integer 1 */ case 9: { /* Integer 1 */
@@ -3048,17 +3061,15 @@ u32 sqlite3VdbeSerialGet(
} }
default: { default: {
static const u16 aFlag[] = { MEM_Blob|MEM_Ephem, MEM_Str|MEM_Ephem }; static const u16 aFlag[] = { MEM_Blob|MEM_Ephem, MEM_Str|MEM_Ephem };
u32 len = (serial_type-12)/2;
pMem->z = (char *)buf; pMem->z = (char *)buf;
pMem->n = len; pMem->n = (serial_type-12)/2;
pMem->xDel = 0; pMem->xDel = 0;
pMem->flags = aFlag[serial_type&1]; pMem->flags = aFlag[serial_type&1];
return len; return pMem->n;
} }
} }
return 0; return 0;
} }
/* /*
** This routine is used to allocate sufficient space for an UnpackedRecord ** This routine is used to allocate sufficient space for an UnpackedRecord
** structure large enough to be used with sqlite3VdbeRecordUnpack() if ** structure large enough to be used with sqlite3VdbeRecordUnpack() if