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-03T16:32:46Z
Lists: pgsql-hackers
Hi,

On 2018-10-03 11:59:27 -0400, Tom Lane wrote:
> I wrote:
> > ... However, I did add recent glibc (Fedora 28)
> > to the mix, and I was interested to discover that they seem to have
> > added a fast-path for format strings that are exactly "%s", just as
> > NetBSD did.  I wonder if we should reconsider our position on doing
> > that.  It'd be a simple enough addition...
> 
> I experimented with adding an initial check for "format is exactly %s"
> at the top of dopr(), and couldn't get excited about that.  Instrumenting
> things showed that the optimization fired in only 1.8% of the calls
> during a run of our core regression tests.  Now, that might not count
> as a really representative workload, but it doesn't make me think that
> the case is worth optimizing for us.

Seems right.  I also have a hard time to believe that any of those "%s"
printfs are performance critical - we'd hopefully just have avoided the
sprintf in that case.


> But then it occurred to me that there's more than one way to skin this
> cat.  We could, for an even cheaper extra test, detect that any one
> format specifier is just "%s", and use the same kind of fast-path
> within the loop.  With the same sort of instrumentation, I found that
> a full 45% of the format specs executed in the core regression tests
> are just %s.  That makes me think that a patch along the lines of the
> attached is a good win for our use-cases.  Comparing to Fedora 28's
> glibc, this gets us to

Hm, especially if we special case the float->string conversions directly
at the hot callsites, that seems reasonable.  I kinda wish we could just
easily move the format string processing to compile-time, but given
translatability that won't be widely possible even if it were otherwise
feasible.

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().