Re: [PATCH 2/2] stdio-common: avoid repeated regexp matches in tst-printf-format.awk
Adhemerval Zanella Netto <[email protected]> Tue, 4 Aug 2026 10:39:23 -0300
| Newsgroups | gmane.comp.lib.glibc.alpha |
|---|---|
| Organization | Linaro |
| Message-ID | <[email protected]> |
On 03/08/26 22:59, Matt Turner wrote: > Whether the value is an infinity, a NaN or zero does not change between > the conversions applied to it, but was determined again for each one. > Determine it where the value is read. > > Also look for the '#' flag with index() before matching the expressions > that need it, and test the value first where both have to hold. > > For the %f conversion for double, in the C locale, as the median of five > runs: > > x86_64, gawk 5.4.1 1.248s -> 1.184s > x86_64, gawk 5.3.2 0.703s -> 0.708s > alpha, gawk 5.4.60 26.6s -> 25.8s > > So this only helps with the regular expression engine that gawk 5.4 > brought in; under 5.3.2 it is lost in the noise. Output and exit status > are unchanged for the e, f and g conversions for double under both > gawk versions and both locales. LGTM, thanks. Reviewed-by: Adhemerval Zanella <[email protected]> > --- > stdio-common/tst-printf-format.awk | 13 ++++++++----- > 1 file changed, 8 insertions(+), 5 deletions(-) > > diff --git ./stdio-common/tst-printf-format.awk ./stdio-common/tst-printf-format.awk > index 5d0324c551..57bea12621 100644 > --- ./stdio-common/tst-printf-format.awk > +++ ./stdio-common/tst-printf-format.awk > @@ -32,6 +32,9 @@ BEGIN { > # non-bignum mode unless a sign has been explicitly given. Keep > # original 'val' for reporting. > value = gensub(/^(INF|NAN|inf|nan)/, "+\\1", 1, val) > + # Neither changes between the conversions applied to this value. > + value_infnan = value ~ /(INF|NAN|inf|nan)/ > + value_zero = value == 0 > next > } > > @@ -52,7 +55,7 @@ BEGIN { > # Discard the '#' flag with the octal conversion if output starts with > # 0 in the absence of this flag. In that case no extra 0 is supposed > # to be produced, but gawk prepends it anyway. > - if (format ~ /#.*o/) > + if (index(format, "#") && format ~ /#.*o/) > { > tmpfmt = gensub(/#/, "", "g", format) > tmpout = sprintf(tmpfmt, value) > @@ -62,7 +65,7 @@ BEGIN { > # Likewise with the hexadecimal conversion where zero value with the > # precision of zero is supposed to produce no characters, but gawk > # outputs 0 instead. > - else if (format ~ /#.*[Xx]/) > + else if (index(format, "#") && format ~ /#.*[Xx]/) > { > tmpfmt = gensub(/#/, "", "g", format) > tmpout = sprintf(tmpfmt, value) > @@ -78,7 +81,7 @@ BEGIN { > # values and reprint the output produced using the string conversion, > # with the field width carried over and the relevant flags handled by > # hand. > - if (format ~ /[EFGefg]/ && value ~ /(INF|NAN|inf|nan)/) > + if (value_infnan && format ~ /[EFGefg]/) > { > minus = format ~ /-/ ? "-" : "" > sign = value ~ /-/ ? "-" : format ~ /\+/ ? "+" : format ~ / / ? " " : "" > @@ -94,7 +97,7 @@ BEGIN { > # In that case "+" is always supposed to be produced, but with the > # precision of zero gawk in the non-bignum mode produces any padding > # requested only. > - else if (format ~ /\+.*[di]/ && value == 0) > + else if (value_zero && format ~ /\+.*[di]/) > { > output = gensub(/^( *) $/, format ~ /-/ ? "+\\1" : "\\1+", 1, output) > output = gensub(/^$/, "+", 1, output) > @@ -103,7 +106,7 @@ BEGIN { > # conversion for zero value. In that case at least one " " is > # supposed to be produced, but with the precision of zero gawk in the > # non-bignum mode produces nothing. > - else if (format ~ / .*[di]/ && value == 0) > + else if (value_zero && format ~ / .*[di]/) > { > output = gensub(/^$/, " ", 1, output) > }