/ Check-in [ea748ede]
Login

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: ea748edecb261f2b862d542daff6e99a6fd8879a8ace94b440d99e110577d1c1
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
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/sqliteInt.h.

  3798   3798   #if defined(SQLITE_ENABLE_MULTITHREADED_CHECKS) && !defined(SQLITE_MUTEX_OMIT)
  3799   3799   void sqlite3MutexWarnOnContention(sqlite3_mutex*);
  3800   3800   #else
  3801   3801   # define sqlite3MutexWarnOnContention(x)
  3802   3802   #endif
  3803   3803   
  3804   3804   #ifndef SQLITE_OMIT_FLOATING_POINT
         3805  +# define EXP754 (((u64)0x7ff)<<52)
         3806  +# define MAN754 ((((u64)1)<<52)-1)
         3807  +# define IsNaN(X) (((X)&EXP754)==EXP754 && ((X)&MAN754)!=0)
  3805   3808     int sqlite3IsNaN(double);
  3806   3809   #else
         3810  +# define IsNaN(X)         0
  3807   3811   # define sqlite3IsNaN(X)  0
  3808   3812   #endif
  3809   3813   
  3810   3814   /*
  3811   3815   ** An instance of the following structure holds information about SQL
  3812   3816   ** functions arguments that are the parameters to the printf() function.
  3813   3817   */

Changes to src/util.c.

    54     54     return xCallback ? xCallback(iTest) : SQLITE_OK;
    55     55   }
    56     56   #endif
    57     57   
    58     58   #ifndef SQLITE_OMIT_FLOATING_POINT
    59     59   /*
    60     60   ** Return true if the floating point value is Not a Number (NaN).
    61         -**
    62         -** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN.
    63         -** Otherwise, we have our own implementation that works on most systems.
    64     61   */
    65     62   int sqlite3IsNaN(double x){
    66         -  int rc;   /* The value return */
    67         -#if !SQLITE_HAVE_ISNAN && !HAVE_ISNAN
    68         -  /*
    69         -  ** Systems that support the isnan() library function should probably
    70         -  ** make use of it by compiling with -DSQLITE_HAVE_ISNAN.  But we have
    71         -  ** found that many systems do not have a working isnan() function so
    72         -  ** this implementation is provided as an alternative.
    73         -  **
    74         -  ** This NaN test sometimes fails if compiled on GCC with -ffast-math.
    75         -  ** On the other hand, the use of -ffast-math comes with the following
    76         -  ** warning:
    77         -  **
    78         -  **      This option [-ffast-math] should never be turned on by any
    79         -  **      -O option since it can result in incorrect output for programs
    80         -  **      which depend on an exact implementation of IEEE or ISO 
    81         -  **      rules/specifications for math functions.
    82         -  **
    83         -  ** Under MSVC, this NaN test may fail if compiled with a floating-
    84         -  ** point precision mode other than /fp:precise.  From the MSDN 
    85         -  ** documentation:
    86         -  **
    87         -  **      The compiler [with /fp:precise] will properly handle comparisons 
    88         -  **      involving NaN. For example, x != x evaluates to true if x is NaN 
    89         -  **      ...
    90         -  */
    91         -#ifdef __FAST_MATH__
    92         -# error SQLite will not work correctly with the -ffast-math option of GCC.
    93         -#endif
    94         -  volatile double y = x;
    95         -  volatile double z = y;
    96         -  rc = (y!=z);
    97         -#else  /* if HAVE_ISNAN */
    98         -  rc = isnan(x);
    99         -#endif /* HAVE_ISNAN */
   100         -  testcase( rc );
   101         -  return rc;
           63  +  u64 y;
           64  +  memcpy(&y,&x,sizeof(y));
           65  +  return IsNaN(y);
   102     66   }
   103     67   #endif /* SQLITE_OMIT_FLOATING_POINT */
   104     68   
   105     69   /*
   106     70   ** Compute a string length that is limited to what can be stored in
   107     71   ** lower 30 bits of a 32-bit signed integer.
   108     72   **

Changes to src/vdbeaux.c.

  3648   3648   ** and store the result in pMem.  Return the number of bytes read.
  3649   3649   **
  3650   3650   ** This function is implemented as two separate routines for performance.
  3651   3651   ** The few cases that require local variables are broken out into a separate
  3652   3652   ** routine so that in most cases the overhead of moving the stack pointer
  3653   3653   ** is avoided.
  3654   3654   */ 
  3655         -static u32 SQLITE_NOINLINE serialGet(
         3655  +static u32 serialGet(
  3656   3656     const unsigned char *buf,     /* Buffer to deserialize from */
  3657   3657     u32 serial_type,              /* Serial type to deserialize */
  3658   3658     Mem *pMem                     /* Memory cell to write value into */
  3659   3659   ){
  3660   3660     u64 x = FOUR_BYTE_UINT(buf);
  3661   3661     u32 y = FOUR_BYTE_UINT(buf+4);
  3662   3662     x = (x<<32) + y;
................................................................................
  3680   3680       u64 t2 = t1;
  3681   3681       swapMixedEndianFloat(t2);
  3682   3682       assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 );
  3683   3683   #endif
  3684   3684       assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 );
  3685   3685       swapMixedEndianFloat(x);
  3686   3686       memcpy(&pMem->u.r, &x, sizeof(x));
  3687         -    pMem->flags = sqlite3IsNaN(pMem->u.r) ? MEM_Null : MEM_Real;
         3687  +    pMem->flags = IsNaN(x) ? MEM_Null : MEM_Real;
  3688   3688     }
  3689   3689     return 8;
  3690   3690   }
  3691   3691   u32 sqlite3VdbeSerialGet(
  3692   3692     const unsigned char *buf,     /* Buffer to deserialize from */
  3693   3693     u32 serial_type,              /* Serial type to deserialize */
  3694   3694     Mem *pMem                     /* Memory cell to write value into */