Re: WIP: Make timestamptz_out less slow.

From: David Rowley <david(dot)rowley(at)2ndquadrant(dot)com>
To: Andres Freund <andres(at)anarazel(dot)de>
Cc: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: WIP: Make timestamptz_out less slow.
Date: 2015-08-05 00:51:43
Message-ID: CAKJS1f_46cttzZ+BD_hrVzqAw1KAuJxVKxCH8Q3HpfP2Z6Orjg@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 29 July 2015 at 03:25, Andres Freund <andres(at)anarazel(dot)de> wrote:

> On 2015-07-29 03:10:41 +1200, David Rowley wrote:
> > timestamp_out() = 2015-07-29 02:24:33.34 in 3.506000
> > timestamp_out_old() = 2015-07-29 02:24:33.034 in 64.518000
> > timestamp_out_af() = 2015-07-29 02:24:33.034 in 2.981000
> >
> > timestamp_out_old is master's version, the timestamp_out_af() is yours,
> and
> > timestamp_out() is my one. times are in seconds to perform 100 million
> > calls.
>
> That looks good.
>
> > So it appears your version is a bit faster than mine, but we're both
> about
> > 20 times faster than the current one.
> > Also mine needs fixed up as the fractional part is not padded the same as
> > yours, but I doubt that'll affect the performance by much.
>
> Worthwhile to finish that bit and try ;)
>
> > My view: It's probably not worth going quite as far as you've gone for a
> > handful of nanoseconds per call, but perhaps something along the lines of
> > mine can be fixed up.
>
> Yes, I agreee that your's is probably going to be fast enough.
>
> > Have you thought about what to do when HAVE_INT64_TIMESTAMP is not
> defined?
>
> I don't think it's actually important. The only difference vs float
> timestamps is that in the latter case we set fsecs to zero BC.
>
> Unless we want to slow down the common case it seems not unlikely that
> we're going to end up with a separate slow path anyway. E.g. neither
> your version nor mine handles 5 digit years (which is why I fell back to
> the slow path in that case in my patch).
>

It occurred to me that handling the 5 digit year is quite a simple change
to my code:

static char *
pg_uint2str_padding(char *str, unsigned int value, unsigned int padding)
{
char *start = str;
char *end = &str[padding];
unsigned int num = value;
//Assert(padding > 0);
*end = '\0';
while (padding--)
{
str[padding] = num % 10 + '0';
num /= 10;
}
/*
* if value was too big for the specified padding then rebuild the whole
* number again without padding. Conveniently pg_uint2str() does exactly
* this.
*/
if (num > 0)
return pg_uint2str(str, value);

return end;
}

We simply just need to check if there was any 'num' left after consuming
the given space. If there's any left then just use pg_uint2str().
This keeps things very fast for the likely most common case where the year
is 4 digits long.

I've not thought about negative years. The whole function should perhaps
take signed ints instead of unsigned.

Regards

David Rowley

--
David Rowley http://www.2ndQuadrant.com/
<http://www.2ndquadrant.com/>
PostgreSQL Development, 24x7 Support, Training & Services

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Michael Paquier 2015-08-05 01:22:15 Re: Doubt about AccessExclusiveLock in ALTER TABLE .. SET ( .. );
Previous Message Michael Paquier 2015-08-05 00:51:30 Re: tablecmds.c and lock hierarchy