/ Check-in [0be3019e]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Reorder the elements of the Mem object for a small size reduction and performance improvement. Moved into a branch because MSVC is unable to handle named structure initializer on nullMem.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | micro-optimizations
Files: files | file ages | folders
SHA1: 0be3019ed794c10de67dfd645ceea7d45815bc4b
User & Date: drh 2014-09-16 14:16:31
Original Comment: Reorder the elements of the Mem object for a small size reduction and performance improvement.
Context
2014-09-16
14:37
Reduce the number of arguments to RecordCompare functions from 4 to 3, resulting in a small performance increase. check-in: 8239c35a user: drh tags: micro-optimizations
14:16
Reorder the elements of the Mem object for a small size reduction and performance improvement. Moved into a branch because MSVC is unable to handle named structure initializer on nullMem. check-in: 0be3019e user: drh tags: micro-optimizations
13:30
Changes to sqlite3VdbeRecordUnpack() to make it slightly smaller and faster. check-in: 8fb90da7 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/func.c.

  1488   1488       cmp = sqlite3MemCompare(pBest, pArg, pColl);
  1489   1489       if( (max && cmp<0) || (!max && cmp>0) ){
  1490   1490         sqlite3VdbeMemCopy(pBest, pArg);
  1491   1491       }else{
  1492   1492         sqlite3SkipAccumulatorLoad(context);
  1493   1493       }
  1494   1494     }else{
         1495  +    pBest->db = sqlite3_context_db_handle(context);
  1495   1496       sqlite3VdbeMemCopy(pBest, pArg);
  1496   1497     }
  1497   1498   }
  1498   1499   static void minMaxFinalize(sqlite3_context *context){
  1499   1500     sqlite3_value *pRes;
  1500   1501     pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0);
  1501   1502     if( pRes ){

Changes to src/vdbeInt.h.

   157    157   
   158    158   /*
   159    159   ** Internally, the vdbe manipulates nearly all SQL values as Mem
   160    160   ** structures. Each Mem struct may cache multiple representations (string,
   161    161   ** integer etc.) of the same value.
   162    162   */
   163    163   struct Mem {
   164         -  sqlite3 *db;        /* The associated database connection */
   165         -  char *z;            /* String or BLOB value */
   166         -  double r;           /* Real value */
   167    164     union {
   168    165       i64 i;              /* Integer value used when MEM_Int is set in flags */
   169    166       int nZero;          /* Used when bit MEM_Zero is set in flags */
   170    167       FuncDef *pDef;      /* Used only when flags==MEM_Agg */
   171    168       RowSet *pRowSet;    /* Used only when flags==MEM_RowSet */
   172    169       VdbeFrame *pFrame;  /* Used when flags==MEM_Frame */
   173    170     } u;
   174         -  int n;              /* Number of characters in string value, excluding '\0' */
   175    171     u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
   176    172     u8  enc;            /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
          173  +  int n;              /* Number of characters in string value, excluding '\0' */
          174  +  double r;           /* Real value */
          175  +  char *z;            /* String or BLOB value */
          176  +  char *zMalloc;      /* Dynamic buffer allocated by sqlite3_malloc() */
          177  +  /* ShallowCopy only needs to copy the information above */
          178  +  sqlite3 *db;        /* The associated database connection */
          179  +  void (*xDel)(void*);/* If not null, call this function to delete Mem.z */
   177    180   #ifdef SQLITE_DEBUG
   178    181     Mem *pScopyFrom;    /* This Mem is a shallow copy of pScopyFrom */
   179    182     void *pFiller;      /* So that sizeof(Mem) is a multiple of 8 */
   180    183   #endif
   181         -  void (*xDel)(void *);  /* If not null, call this function to delete Mem.z */
   182         -  char *zMalloc;      /* Dynamic buffer allocated by sqlite3_malloc() */
   183    184   };
   184    185   
   185    186   /* One or more of the following flags are set to indicate the validOK
   186    187   ** representations of the value stored in the Mem struct.
   187    188   **
   188    189   ** If the MEM_Null flag is set, then the value is an SQL NULL value.
   189    190   ** No other flags may be set in this case.

Changes to src/vdbeapi.c.

   799    799     ** these assert()s from failing, when building with SQLITE_DEBUG defined
   800    800     ** using gcc, we force nullMem to be 8-byte aligned using the magical
   801    801     ** __attribute__((aligned(8))) macro.  */
   802    802     static const Mem nullMem 
   803    803   #if defined(SQLITE_DEBUG) && defined(__GNUC__)
   804    804       __attribute__((aligned(8))) 
   805    805   #endif
   806         -    = {0, "", (double)0, {0}, 0, MEM_Null, 0,
          806  +    = {
          807  +         .flags      = MEM_Null,
          808  +         .enc        = 0,
          809  +         .n          = 0,
          810  +         .r          = (double)0,
          811  +         .u          = {0},
          812  +         .z          = 0,
          813  +         .zMalloc    = 0,
          814  +         .db         = 0,
          815  +         .xDel       = 0,
   807    816   #ifdef SQLITE_DEBUG
   808         -       0, 0,  /* pScopyFrom, pFiller */
          817  +         .pScopyFrom = 0,
          818  +         .pFiller    = 0,
   809    819   #endif
   810         -       0, 0 };
          820  +      };
   811    821     return &nullMem;
   812    822   }
   813    823   
   814    824   /*
   815    825   ** Check to see if column iCol of the given statement is valid.  If
   816    826   ** it is, return a pointer to the Mem for the value of that column.
   817    827   ** If iCol is not valid, return a pointer to a Mem which has a value

Changes to src/vdbeaux.c.

  3299   3299       return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z);
  3300   3300     }else{
  3301   3301       int rc;
  3302   3302       const void *v1, *v2;
  3303   3303       int n1, n2;
  3304   3304       Mem c1;
  3305   3305       Mem c2;
  3306         -    memset(&c1, 0, sizeof(c1));
  3307         -    memset(&c2, 0, sizeof(c2));
         3306  +    c1.db = c2.db = pMem1->db;
         3307  +    c1.flags = c2.flags = 0;
         3308  +    c1.zMalloc = c2.zMalloc = 0;
  3308   3309       sqlite3VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem);
  3309   3310       sqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem);
  3310   3311       v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc);
  3311   3312       n1 = v1==0 ? 0 : c1.n;
  3312   3313       v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc);
  3313   3314       n2 = v2==0 ? 0 : c2.n;
  3314   3315       rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2);

Changes to src/vdbemem.c.

   726    726   ** Make an shallow copy of pFrom into pTo.  Prior contents of
   727    727   ** pTo are freed.  The pFrom->z field is not duplicated.  If
   728    728   ** pFrom->z is used, then pTo->z points to the same thing as pFrom->z
   729    729   ** and flags gets srcType (either MEM_Ephem or MEM_Static).
   730    730   */
   731    731   void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
   732    732     assert( (pFrom->flags & MEM_RowSet)==0 );
          733  +  assert( pTo->db==pFrom->db );
   733    734     VdbeMemReleaseExtern(pTo);
   734    735     memcpy(pTo, pFrom, MEMCELLSIZE);
   735    736     pTo->xDel = 0;
   736    737     if( (pFrom->flags&MEM_Static)==0 ){
   737    738       pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem);
   738    739       assert( srcType==MEM_Ephem || srcType==MEM_Static );
   739    740       pTo->flags |= srcType;
................................................................................
   743    744   /*
   744    745   ** Make a full copy of pFrom into pTo.  Prior contents of pTo are
   745    746   ** freed before the copy is made.
   746    747   */
   747    748   int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
   748    749     int rc = SQLITE_OK;
   749    750   
          751  +  assert( pTo->db==pFrom->db );
   750    752     assert( (pFrom->flags & MEM_RowSet)==0 );
   751    753     VdbeMemReleaseExtern(pTo);
   752    754     memcpy(pTo, pFrom, MEMCELLSIZE);
   753    755     pTo->flags &= ~MEM_Dyn;
   754    756     pTo->xDel = 0;
   755    757   
   756    758     if( pTo->flags&(MEM_Str|MEM_Blob) ){