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-03T18:35:52Z
Lists: pgsql-hackers
Hi,

On 2018-10-03 14:01:35 -0400, Tom Lane wrote:
> Andres Freund <andres@anarazel.de> writes:
> > So when using pg's snprintf() to print a single floating point number
> > with precision, we get nearly a 10% boost.
> 
> I just tested that using my little standalone testbed, and I failed
> to replicate the result.  I do see that strfromd is slightly faster,
> but it's just a few percent measuring snprintf.c in isolation --- in
> the overall context of COPY, I don't see how you get to 10% net savings.

I just tested your patch, and I see (best of three):

master:
16224.727 ms
hack-use-of-strfromd.patch:
14944.927 ms

So not quite 10%, but pretty close.


CREATE TABLE somefloats(id serial, data1 float8, data2 float8, data3 float8);
INSERT INTO somefloats(data1, data2, data3) SELECT random(), random(), random() FROM generate_series(1, 10000000);
VACUUM FREEZE somefloats;

COPY somefloats TO '/dev/null';

What difference do you see?


> So I continue to think there's something fishy about your test case.
> 
> BTW, so far as I can tell on F28, strfromd isn't exposed without
> "-D__STDC_WANT_IEC_60559_BFP_EXT__", which seems fairly scary;
> what else does that affect?

My copy says:

#undef __GLIBC_USE_IEC_60559_BFP_EXT
#if defined __USE_GNU || defined __STDC_WANT_IEC_60559_BFP_EXT__
# define __GLIBC_USE_IEC_60559_BFP_EXT 1
#else
# define __GLIBC_USE_IEC_60559_BFP_EXT 0
#endif

And __USE_GNU is enabled by
#ifdef	_GNU_SOURCE
# define __USE_GNU	1
#endif

So I don't think anything's needed to enable that in pg, given that we
define _GNU_SOURCE


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