Re: Performance improvements for src/port/snprintf.c

Andres Freund <andres@anarazel.de>

From: Andres Freund <andres@anarazel.de>
To: Tom Lane <tgl@sss.pgh.pa.us>
Cc: pgsql-hackers@lists.postgresql.org, Thomas Munro <thomas.munro@enterprisedb.com>, Andrew Gierth <andrew@tao11.riddles.org.uk>, Alexander Kuzmenkov <a.kuzmenkov@postgrespro.ru>
Date: 2018-10-03T17:00:43Z
Lists: pgsql-hackers
Hi,

On 2018-10-03 12:54:52 -0400, Tom Lane wrote:
> Andres Freund <andres@anarazel.de> writes:
> > It seems the general "use strfromd if available" approach is generally
> > useful, even if we need to serialize the precision.
> 
> Agreed.
> 
> > Putting it into an
> > inline appears to be helpful, avoids some of the otherwise precision
> > related branches.  Do you have any feelings about which header to put
> > the code in?  I used common/string.h so far.
> 
> I do not think it should be in a header, for two reasons:
> 
> (1) The need to use sprintf for portability means that we need very
> tight constraints on the precision spec *and* the buffer size *and*
> the format type (%f pretty much destroys certainty about how long the
> output string is).  So this isn't going to be general purpose code.
> I think just writing it into float[48]out is sufficient.

Well, the numbers suggest it's also useful to do so from snprintf - it's
not that rare that we output floating point numbers from semi
performance critical code, even leaving aside float[48]out.  So I'm not
convinced that we shouldn't do this from within snprintf.c too. Now we
could open-code it twice, but i'm not sure I see the point.

If we just define the API as having to guarantee there's enough space
for the output format, I think it'll work well enough for now?
snprintf.c already assumes everything floating point can be output in
1024 chars, no?

Greetings,

Andres Freund


Commits

  1. Improve snprintf.c's handling of NaN, Infinity, and minus zero.

  2. Rationalize snprintf.c's handling of "ll" formats.

  3. Provide fast path in snprintf.c for conversion specs that are just "%s".

  4. Make assorted performance improvements in snprintf.c.

  5. Set snprintf.c's maximum number of NL arguments to be 31.

  6. Always use our own versions of *printf().