Fossil SCM

Performance optimization in the internal printf() implementation.

drh 2020-11-21 14:10 trunk
Commit 008fc9290cbbaa57ffdfab939d0cbced32c4971bbf1fdbab25cd323f0b54ee18
2 files changed +1 +25 -8
+1
--- src/main.c
+++ src/main.c
@@ -673,10 +673,11 @@
673673
#endif
674674
}
675675
}
676676
#endif
677677
678
+ fossil_printf_selfcheck();
678679
fossil_limit_memory(1);
679680
if( sqlite3_libversion_number()<3034000 ){
680681
fossil_panic("Unsuitable SQLite version %s, must be at least 3.34.0",
681682
sqlite3_libversion());
682683
}
683684
--- src/main.c
+++ src/main.c
@@ -673,10 +673,11 @@
673 #endif
674 }
675 }
676 #endif
677
 
678 fossil_limit_memory(1);
679 if( sqlite3_libversion_number()<3034000 ){
680 fossil_panic("Unsuitable SQLite version %s, must be at least 3.34.0",
681 sqlite3_libversion());
682 }
683
--- src/main.c
+++ src/main.c
@@ -673,10 +673,11 @@
673 #endif
674 }
675 }
676 #endif
677
678 fossil_printf_selfcheck();
679 fossil_limit_memory(1);
680 if( sqlite3_libversion_number()<3034000 ){
681 fossil_panic("Unsuitable SQLite version %s, must be at least 3.34.0",
682 sqlite3_libversion());
683 }
684
+25 -8
--- src/printf.c
+++ src/printf.c
@@ -134,13 +134,17 @@
134134
135135
136136
/*
137137
** The following table is searched linearly, so it is good to put the
138138
** most frequently used conversion types first.
139
+**
140
+** NB: When modifying this table is it vital that you also update the fmtchr[]
141
+** variable to match!!!
139142
*/
140143
static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
141144
static const char aPrefix[] = "-x0\000X0";
145
+static const char fmtchr[] = "dsgzqQbBWhRtTwFSjcouxXfeEGin%p/$";
142146
static const et_info fmtinfo[] = {
143147
{ 'd', 10, 1, etRADIX, 0, 0 },
144148
{ 's', 0, 4, etSTRING, 0, 0 },
145149
{ 'g', 0, 1, etGENERIC, 30, 0 },
146150
{ 'z', 0, 6, etDYNSTRING, 0, 0 },
@@ -172,10 +176,23 @@
172176
{ 'p', 16, 0, etPOINTER, 0, 1 },
173177
{ '/', 0, 0, etPATH, 0, 0 },
174178
{ '$', 0, 0, etSHELLESC, 0, 0 },
175179
};
176180
#define etNINFO count(fmtinfo)
181
+
182
+/*
183
+** Verify that the fmtchr[] and fmtinfo[] arrays are in agreement.
184
+**
185
+** This routine is a defense against programming errors.
186
+*/
187
+void fossil_printf_selfcheck(void){
188
+ int i;
189
+ for(i=0; fmtchr[i]; i++){
190
+ assert( fmtchr[i]==fmtinfo[i].fmttype );
191
+ }
192
+}
193
+
177194
178195
/*
179196
** "*val" is a double such that 0.1 <= *val < 10.0
180197
** Return the ascii code for the leading digit of *val, then
181198
** multiply "*val" by 10.0 to renormalize.
@@ -306,10 +323,11 @@
306323
double rounder; /* Used for rounding floating point values */
307324
etByte flag_dp; /* True if decimal point should be shown */
308325
etByte flag_rtz; /* True if trailing zeros should be removed */
309326
etByte flag_exp; /* True to force display of the exponent */
310327
int nsd; /* Number of significant digits returned */
328
+ char *zFmtLookup;
311329
312330
count = length = 0;
313331
bufpt = 0;
314332
for(; (c=(*fmt))!=0; ++fmt){
315333
if( c!='%' ){
@@ -390,18 +408,17 @@
390408
}
391409
}else{
392410
flag_long = flag_longlong = 0;
393411
}
394412
/* Fetch the info entry for the field */
395
- infop = 0;
396
- xtype = etERROR;
397
- for(idx=0; idx<etNINFO; idx++){
398
- if( c==fmtinfo[idx].fmttype ){
399
- infop = &fmtinfo[idx];
400
- xtype = infop->type;
401
- break;
402
- }
413
+ zFmtLookup = strchr(fmtchr,c);
414
+ if( zFmtLookup ){
415
+ infop = &fmtinfo[zFmtLookup-fmtchr];
416
+ xtype = infop->type;
417
+ }else{
418
+ infop = 0;
419
+ xtype = etERROR;
403420
}
404421
zExtra = 0;
405422
406423
/* Limit the precision to prevent overflowing buf[] during conversion */
407424
if( precision>etBUFSIZE-40 && (infop->flags & FLAG_STRING)==0 ){
408425
--- src/printf.c
+++ src/printf.c
@@ -134,13 +134,17 @@
134
135
136 /*
137 ** The following table is searched linearly, so it is good to put the
138 ** most frequently used conversion types first.
 
 
 
139 */
140 static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
141 static const char aPrefix[] = "-x0\000X0";
 
142 static const et_info fmtinfo[] = {
143 { 'd', 10, 1, etRADIX, 0, 0 },
144 { 's', 0, 4, etSTRING, 0, 0 },
145 { 'g', 0, 1, etGENERIC, 30, 0 },
146 { 'z', 0, 6, etDYNSTRING, 0, 0 },
@@ -172,10 +176,23 @@
172 { 'p', 16, 0, etPOINTER, 0, 1 },
173 { '/', 0, 0, etPATH, 0, 0 },
174 { '$', 0, 0, etSHELLESC, 0, 0 },
175 };
176 #define etNINFO count(fmtinfo)
 
 
 
 
 
 
 
 
 
 
 
 
 
177
178 /*
179 ** "*val" is a double such that 0.1 <= *val < 10.0
180 ** Return the ascii code for the leading digit of *val, then
181 ** multiply "*val" by 10.0 to renormalize.
@@ -306,10 +323,11 @@
306 double rounder; /* Used for rounding floating point values */
307 etByte flag_dp; /* True if decimal point should be shown */
308 etByte flag_rtz; /* True if trailing zeros should be removed */
309 etByte flag_exp; /* True to force display of the exponent */
310 int nsd; /* Number of significant digits returned */
 
311
312 count = length = 0;
313 bufpt = 0;
314 for(; (c=(*fmt))!=0; ++fmt){
315 if( c!='%' ){
@@ -390,18 +408,17 @@
390 }
391 }else{
392 flag_long = flag_longlong = 0;
393 }
394 /* Fetch the info entry for the field */
395 infop = 0;
396 xtype = etERROR;
397 for(idx=0; idx<etNINFO; idx++){
398 if( c==fmtinfo[idx].fmttype ){
399 infop = &fmtinfo[idx];
400 xtype = infop->type;
401 break;
402 }
403 }
404 zExtra = 0;
405
406 /* Limit the precision to prevent overflowing buf[] during conversion */
407 if( precision>etBUFSIZE-40 && (infop->flags & FLAG_STRING)==0 ){
408
--- src/printf.c
+++ src/printf.c
@@ -134,13 +134,17 @@
134
135
136 /*
137 ** The following table is searched linearly, so it is good to put the
138 ** most frequently used conversion types first.
139 **
140 ** NB: When modifying this table is it vital that you also update the fmtchr[]
141 ** variable to match!!!
142 */
143 static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
144 static const char aPrefix[] = "-x0\000X0";
145 static const char fmtchr[] = "dsgzqQbBWhRtTwFSjcouxXfeEGin%p/$";
146 static const et_info fmtinfo[] = {
147 { 'd', 10, 1, etRADIX, 0, 0 },
148 { 's', 0, 4, etSTRING, 0, 0 },
149 { 'g', 0, 1, etGENERIC, 30, 0 },
150 { 'z', 0, 6, etDYNSTRING, 0, 0 },
@@ -172,10 +176,23 @@
176 { 'p', 16, 0, etPOINTER, 0, 1 },
177 { '/', 0, 0, etPATH, 0, 0 },
178 { '$', 0, 0, etSHELLESC, 0, 0 },
179 };
180 #define etNINFO count(fmtinfo)
181
182 /*
183 ** Verify that the fmtchr[] and fmtinfo[] arrays are in agreement.
184 **
185 ** This routine is a defense against programming errors.
186 */
187 void fossil_printf_selfcheck(void){
188 int i;
189 for(i=0; fmtchr[i]; i++){
190 assert( fmtchr[i]==fmtinfo[i].fmttype );
191 }
192 }
193
194
195 /*
196 ** "*val" is a double such that 0.1 <= *val < 10.0
197 ** Return the ascii code for the leading digit of *val, then
198 ** multiply "*val" by 10.0 to renormalize.
@@ -306,10 +323,11 @@
323 double rounder; /* Used for rounding floating point values */
324 etByte flag_dp; /* True if decimal point should be shown */
325 etByte flag_rtz; /* True if trailing zeros should be removed */
326 etByte flag_exp; /* True to force display of the exponent */
327 int nsd; /* Number of significant digits returned */
328 char *zFmtLookup;
329
330 count = length = 0;
331 bufpt = 0;
332 for(; (c=(*fmt))!=0; ++fmt){
333 if( c!='%' ){
@@ -390,18 +408,17 @@
408 }
409 }else{
410 flag_long = flag_longlong = 0;
411 }
412 /* Fetch the info entry for the field */
413 zFmtLookup = strchr(fmtchr,c);
414 if( zFmtLookup ){
415 infop = &fmtinfo[zFmtLookup-fmtchr];
416 xtype = infop->type;
417 }else{
418 infop = 0;
419 xtype = etERROR;
 
420 }
421 zExtra = 0;
422
423 /* Limit the precision to prevent overflowing buf[] during conversion */
424 if( precision>etBUFSIZE-40 && (infop->flags & FLAG_STRING)==0 ){
425

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button