Fossil

Check-in [008fc9290c]
Login

Check-in [008fc9290c]

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

Overview
Comment:Performance optimization in the internal printf() implementation.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 008fc9290cbbaa57ffdfab939d0cbced32c4971bbf1fdbab25cd323f0b54ee18
User & Date: drh 2020-11-21 14:10:26.748
Context
2020-11-21
14:34
Further performance improvements to the internal printf() implementation. ... (check-in: 3ad620df00 user: drh tags: trunk)
14:10
Performance optimization in the internal printf() implementation. ... (check-in: 008fc9290c user: drh tags: trunk)
2020-11-20
19:44
Fix a C++-ism in the import code. ... (check-in: 87c4b7c48c user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/main.c.
671
672
673
674
675
676
677

678
679
680
681
682
683
684
#elif defined(SIGTRAP)
      raise(SIGTRAP);
#endif
    }
  }
#endif


  fossil_limit_memory(1);
  if( sqlite3_libversion_number()<3034000 ){
    fossil_panic("Unsuitable SQLite version %s, must be at least 3.34.0",
                 sqlite3_libversion());
  }
  sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
  sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);







>







671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
#elif defined(SIGTRAP)
      raise(SIGTRAP);
#endif
    }
  }
#endif

  fossil_printf_selfcheck();
  fossil_limit_memory(1);
  if( sqlite3_libversion_number()<3034000 ){
    fossil_panic("Unsuitable SQLite version %s, must be at least 3.34.0",
                 sqlite3_libversion());
  }
  sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
  sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
Changes to src/printf.c.
132
133
134
135
136
137
138



139
140
141

142
143
144
145
146
147
148
#define FLAG_INTERN  2     /* True if for internal use only */
#define FLAG_STRING  4     /* Allow infinity precision */


/*
** The following table is searched linearly, so it is good to put the
** most frequently used conversion types first.



*/
static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
static const char aPrefix[] = "-x0\000X0";

static const et_info fmtinfo[] = {
  {  'd', 10, 1, etRADIX,      0,  0 },
  {  's',  0, 4, etSTRING,     0,  0 },
  {  'g',  0, 1, etGENERIC,    30, 0 },
  {  'z',  0, 6, etDYNSTRING,  0,  0 },
  {  'q',  0, 4, etSQLESCAPE,  0,  0 },
  {  'Q',  0, 4, etSQLESCAPE2, 0,  0 },







>
>
>



>







132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#define FLAG_INTERN  2     /* True if for internal use only */
#define FLAG_STRING  4     /* Allow infinity precision */


/*
** The following table is searched linearly, so it is good to put the
** most frequently used conversion types first.
**
** NB: When modifying this table is it vital that you also update the fmtchr[]
** variable to match!!!
*/
static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
static const char aPrefix[] = "-x0\000X0";
static const char fmtchr[] = "dsgzqQbBWhRtTwFSjcouxXfeEGin%p/$";
static const et_info fmtinfo[] = {
  {  'd', 10, 1, etRADIX,      0,  0 },
  {  's',  0, 4, etSTRING,     0,  0 },
  {  'g',  0, 1, etGENERIC,    30, 0 },
  {  'z',  0, 6, etDYNSTRING,  0,  0 },
  {  'q',  0, 4, etSQLESCAPE,  0,  0 },
  {  'Q',  0, 4, etSQLESCAPE2, 0,  0 },
170
171
172
173
174
175
176













177
178
179
180
181
182
183
  {  'n',  0, 0, etSIZE,       0,  0 },
  {  '%',  0, 0, etPERCENT,    0,  0 },
  {  'p', 16, 0, etPOINTER,    0,  1 },
  {  '/',  0, 0, etPATH,       0,  0 },
  {  '$',  0, 0, etSHELLESC,   0,  0 },
};
#define etNINFO count(fmtinfo)














/*
** "*val" is a double such that 0.1 <= *val < 10.0
** Return the ascii code for the leading digit of *val, then
** multiply "*val" by 10.0 to renormalize.
**
** Example:







>
>
>
>
>
>
>
>
>
>
>
>
>







174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
  {  'n',  0, 0, etSIZE,       0,  0 },
  {  '%',  0, 0, etPERCENT,    0,  0 },
  {  'p', 16, 0, etPOINTER,    0,  1 },
  {  '/',  0, 0, etPATH,       0,  0 },
  {  '$',  0, 0, etSHELLESC,   0,  0 },
};
#define etNINFO count(fmtinfo)

/*
** Verify that the fmtchr[] and fmtinfo[] arrays are in agreement.
**
** This routine is a defense against programming errors.
*/
void fossil_printf_selfcheck(void){
  int i;
  for(i=0; fmtchr[i]; i++){
    assert( fmtchr[i]==fmtinfo[i].fmttype );
  }
}


/*
** "*val" is a double such that 0.1 <= *val < 10.0
** Return the ascii code for the leading digit of *val, then
** multiply "*val" by 10.0 to renormalize.
**
** Example:
304
305
306
307
308
309
310

311
312
313
314
315
316
317
#define etSPACESIZE (sizeof(spaces)-1)
  int  exp, e2;              /* exponent of real numbers */
  double rounder;            /* Used for rounding floating point values */
  etByte flag_dp;            /* True if decimal point should be shown */
  etByte flag_rtz;           /* True if trailing zeros should be removed */
  etByte flag_exp;           /* True to force display of the exponent */
  int nsd;                   /* Number of significant digits returned */


  count = length = 0;
  bufpt = 0;
  for(; (c=(*fmt))!=0; ++fmt){
    if( c!='%' ){
      int amt;
      bufpt = (char *)fmt;







>







321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
#define etSPACESIZE (sizeof(spaces)-1)
  int  exp, e2;              /* exponent of real numbers */
  double rounder;            /* Used for rounding floating point values */
  etByte flag_dp;            /* True if decimal point should be shown */
  etByte flag_rtz;           /* True if trailing zeros should be removed */
  etByte flag_exp;           /* True to force display of the exponent */
  int nsd;                   /* Number of significant digits returned */
  char *zFmtLookup;

  count = length = 0;
  bufpt = 0;
  for(; (c=(*fmt))!=0; ++fmt){
    if( c!='%' ){
      int amt;
      bufpt = (char *)fmt;
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402


403
404
405
406
407
408
409
      }else{
        flag_longlong = 0;
      }
    }else{
      flag_long = flag_longlong = 0;
    }
    /* Fetch the info entry for the field */
    infop = 0;
    xtype = etERROR;
    for(idx=0; idx<etNINFO; idx++){
      if( c==fmtinfo[idx].fmttype ){
        infop = &fmtinfo[idx];
        xtype = infop->type;
        break;
      }


    }
    zExtra = 0;

    /* Limit the precision to prevent overflowing buf[] during conversion */
    if( precision>etBUFSIZE-40 && (infop->flags & FLAG_STRING)==0 ){
      precision = etBUFSIZE-40;
    }







|
<
<
|
|
|
<
|
>
>







406
407
408
409
410
411
412
413


414
415
416

417
418
419
420
421
422
423
424
425
426
      }else{
        flag_longlong = 0;
      }
    }else{
      flag_long = flag_longlong = 0;
    }
    /* Fetch the info entry for the field */
    zFmtLookup = strchr(fmtchr,c);


    if( zFmtLookup ){
      infop = &fmtinfo[zFmtLookup-fmtchr];
      xtype = infop->type;

    }else{
      infop = 0;
      xtype = etERROR;
    }
    zExtra = 0;

    /* Limit the precision to prevent overflowing buf[] during conversion */
    if( precision>etBUFSIZE-40 && (infop->flags & FLAG_STRING)==0 ){
      precision = etBUFSIZE-40;
    }