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

From: Andres Freund <andres(at)anarazel(dot)de>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: pgsql-hackers(at)lists(dot)postgresql(dot)org, Thomas Munro <thomas(dot)munro(at)enterprisedb(dot)com>, Andrew Gierth <andrew(at)tao11(dot)riddles(dot)org(dot)uk>, Alexander Kuzmenkov <a(dot)kuzmenkov(at)postgrespro(dot)ru>
Subject: Re: Performance improvements for src/port/snprintf.c
Date: 2018-10-03 06:09:36
Message-ID: 20181003060936.zul7mfkcu5w7rotg@alap3.anarazel.de
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 2018-10-02 17:54:31 -0400, Tom Lane wrote:
> Here's a version of this patch rebased over commit 625b38ea0.
>
> That commit's fix for the possibly-expensive memset means that we need
> to reconsider performance numbers for this patch. I re-ran my previous
> tests, and it's still looking like this is a substantial win, as it makes
> snprintf.c faster than the native snprintf for most non-float cases.
> We're still stuck at something like 10% penalty for float cases.

Cool. Let's get that in...

> While there might be value in implementing our own float printing code,
> I have a pretty hard time getting excited about the cost/benefit ratio
> of that. I think that what we probably really ought to do here is hack
> float4out/float8out to bypass the extra overhead, as in the 0002 patch
> below.

I'm thinking we should do a bit more than just that hack. I'm thinking
of something (barely tested) like

int
pg_double_to_string(char *buf, size_t bufsize, char tp, int precision, double val)
{
char fmt[8];

#ifdef HAVE_STRFROMD

if (precision != -1)
{
fmt[0] = '%';
fmt[1] = '.';
fmt[2] = '0' + precision / 10;
fmt[3] = '0' + precision % 10;
fmt[4] = tp;
fmt[5] = '\0';
}
else
{
fmt[0] = '%';
fmt[1] = tp;
fmt[2] = '\0';
}

return strfromd(buf, bufsize, fmt, val);
#else

if (precision != -1)
{
fmt[0] = '%';
fmt[1] = '.';
fmt[2] = '*';
fmt[3] = tp;
fmt[4] = '\0';
}
else
{
fmt[0] = '%';
fmt[1] = tp;
fmt[2] = '\0';
}

#undef snprintf
return snprintf(buf, bufsize, fmt, precision, val);
#define sprintf pg_snprintf
#endif
}

and putting that in string.h or such.

Then we'd likely be faster both when going through pg_sprintf etc when
strfromd is available, and by using it directly in float8out etc, we'd
be at least as fast as before.

I can clean that up, just not tonight.

FWIW, I think there's still a significant argument to be made that we
should work on our floating point IO performance. Both on the input and
output side. It's a significant practical problem. But both a fix like
you describe, and my proposal, should bring us to at least the previous
level of performance for the hot paths. So that'd then just be an
independent consideration.

Greetings,

Andres Freund

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Ideriha, Takeshi 2018-10-03 06:17:35 RE: Global shared meta cache
Previous Message Andrey Borodin 2018-10-03 05:54:14 Re: [WIP PATCH] Index scan offset optimisation using visibility map