Re: Performance improvements for src/port/snprintf.c - Mailing list pgsql-hackers

From Andres Freund
Subject Re: Performance improvements for src/port/snprintf.c
Date
Msg-id 20181003060936.zul7mfkcu5w7rotg@alap3.anarazel.de
Whole thread Raw
In response to Re: Performance improvements for src/port/snprintf.c  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: Performance improvements for src/port/snprintf.c  (Tom Lane <tgl@sss.pgh.pa.us>)
List 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


pgsql-hackers by date:

Previous
From: Andrey Borodin
Date:
Subject: Re: [WIP PATCH] Index scan offset optimisation using visibility map
Next
From: "Ideriha, Takeshi"
Date:
Subject: RE: Global shared meta cache