Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Smaller and faster sqlite3IsNaN() implementation makes deserialization of floating point values much faster. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
ea748edecb261f2b862d542daff6e99a |
User & Date: | drh 2019-05-30 00:46:37 |
Context
2019-05-30
| ||
13:47 | Optimization to the round() SQL function for large input values without a fractional part. check-in: e95138f5 user: drh tags: trunk | |
00:46 | Smaller and faster sqlite3IsNaN() implementation makes deserialization of floating point values much faster. check-in: ea748ede user: drh tags: trunk | |
2019-05-29
| ||
21:18 | Much faster implementation of applyNumericAffinity() by avoiding some unnecessary calls to sqlite3Atoi64(). check-in: c1d8a3f6 user: drh tags: trunk | |
Changes
Changes to src/sqliteInt.h.
3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 |
#if defined(SQLITE_ENABLE_MULTITHREADED_CHECKS) && !defined(SQLITE_MUTEX_OMIT) void sqlite3MutexWarnOnContention(sqlite3_mutex*); #else # define sqlite3MutexWarnOnContention(x) #endif #ifndef SQLITE_OMIT_FLOATING_POINT int sqlite3IsNaN(double); #else # define sqlite3IsNaN(X) 0 #endif /* ** An instance of the following structure holds information about SQL ** functions arguments that are the parameters to the printf() function. */ |
> > > > |
3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 |
#if defined(SQLITE_ENABLE_MULTITHREADED_CHECKS) && !defined(SQLITE_MUTEX_OMIT) void sqlite3MutexWarnOnContention(sqlite3_mutex*); #else # define sqlite3MutexWarnOnContention(x) #endif #ifndef SQLITE_OMIT_FLOATING_POINT # define EXP754 (((u64)0x7ff)<<52) # define MAN754 ((((u64)1)<<52)-1) # define IsNaN(X) (((X)&EXP754)==EXP754 && ((X)&MAN754)!=0) int sqlite3IsNaN(double); #else # define IsNaN(X) 0 # define sqlite3IsNaN(X) 0 #endif /* ** An instance of the following structure holds information about SQL ** functions arguments that are the parameters to the printf() function. */ |
Changes to src/util.c.
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
return xCallback ? xCallback(iTest) : SQLITE_OK; } #endif #ifndef SQLITE_OMIT_FLOATING_POINT /* ** Return true if the floating point value is Not a Number (NaN). ** ** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN. ** Otherwise, we have our own implementation that works on most systems. */ int sqlite3IsNaN(double x){ int rc; /* The value return */ #if !SQLITE_HAVE_ISNAN && !HAVE_ISNAN /* ** Systems that support the isnan() library function should probably ** make use of it by compiling with -DSQLITE_HAVE_ISNAN. But we have ** found that many systems do not have a working isnan() function so ** this implementation is provided as an alternative. ** ** This NaN test sometimes fails if compiled on GCC with -ffast-math. ** On the other hand, the use of -ffast-math comes with the following ** warning: ** ** This option [-ffast-math] should never be turned on by any ** -O option since it can result in incorrect output for programs ** which depend on an exact implementation of IEEE or ISO ** rules/specifications for math functions. ** ** Under MSVC, this NaN test may fail if compiled with a floating- ** point precision mode other than /fp:precise. From the MSDN ** documentation: ** ** The compiler [with /fp:precise] will properly handle comparisons ** involving NaN. For example, x != x evaluates to true if x is NaN ** ... */ #ifdef __FAST_MATH__ # error SQLite will not work correctly with the -ffast-math option of GCC. #endif volatile double y = x; volatile double z = y; rc = (y!=z); #else /* if HAVE_ISNAN */ rc = isnan(x); #endif /* HAVE_ISNAN */ testcase( rc ); return rc; } #endif /* SQLITE_OMIT_FLOATING_POINT */ /* ** Compute a string length that is limited to what can be stored in ** lower 30 bits of a 32-bit signed integer. ** |
< < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < > > | |
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
return xCallback ? xCallback(iTest) : SQLITE_OK; } #endif #ifndef SQLITE_OMIT_FLOATING_POINT /* ** Return true if the floating point value is Not a Number (NaN). */ int sqlite3IsNaN(double x){ u64 y; memcpy(&y,&x,sizeof(y)); return IsNaN(y); } #endif /* SQLITE_OMIT_FLOATING_POINT */ /* ** Compute a string length that is limited to what can be stored in ** lower 30 bits of a 32-bit signed integer. ** |
Changes to src/vdbeaux.c.
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
....
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
|
** 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. */ static u32 SQLITE_NOINLINE serialGet( const unsigned char *buf, /* Buffer to deserialize from */ u32 serial_type, /* Serial type to deserialize */ Mem *pMem /* Memory cell to write value into */ ){ u64 x = FOUR_BYTE_UINT(buf); u32 y = FOUR_BYTE_UINT(buf+4); x = (x<<32) + y; ................................................................................ u64 t2 = t1; swapMixedEndianFloat(t2); assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 ); #endif assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 ); swapMixedEndianFloat(x); memcpy(&pMem->u.r, &x, sizeof(x)); pMem->flags = sqlite3IsNaN(pMem->u.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 */ |
|
|
|
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
....
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
|
** 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. */ static u32 serialGet( const unsigned char *buf, /* Buffer to deserialize from */ u32 serial_type, /* Serial type to deserialize */ Mem *pMem /* Memory cell to write value into */ ){ u64 x = FOUR_BYTE_UINT(buf); u32 y = FOUR_BYTE_UINT(buf+4); x = (x<<32) + y; ................................................................................ u64 t2 = t1; swapMixedEndianFloat(t2); assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 ); #endif assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 ); swapMixedEndianFloat(x); memcpy(&pMem->u.r, &x, sizeof(x)); pMem->flags = IsNaN(x) ? 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 */ |