From: | Jeremy Kerr <jk(at)ozlabs(dot)org> |
---|---|
To: | <pgsql-hackers(at)postgresql(dot)org> |
Cc: | Stephen Frost <sfrost(at)snowman(dot)net>, Robert Haas <robertmhaas(at)gmail(dot)com>, Alvaro Herrera <alvherre(at)commandprompt(dot)com>, Stefan Kaltenbrunner <stefan(at)kaltenbrunner(dot)cc>, Gurjeet Singh <singh(dot)gurjeet(at)gmail(dot)com> |
Subject: | [PATCH] backend: compare word-at-a-time in bcTruelen |
Date: | 2009-06-24 01:05:03 |
Message-ID: | 1245805503.62025.32374376046.1.gpush@pingu |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
The current bcTruelen function uses a simple reverse array scan to
find the legth of a space-padded string. On some workloads (it shows
in sysbench), this can result in a lot of time spent in this function.
This change introduces a word-at-a-time comparison in bcTruelen, aiming
to reduce the number of compares where possible. Word-size compares
are performed on aligned sections of the string.
Results in a small performance increase; around 1-2% on my POWER6 test
box.
Signed-off-by: Jeremy Kerr <jk(at)ozlabs(dot)org>
---
Resend: context diff this time
---
src/backend/utils/adt/varchar.c | 24 +++++++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)
*** a/src/backend/utils/adt/varchar.c
--- b/src/backend/utils/adt/varchar.c
***************
*** 624,639 **** varchartypmodout(PG_FUNCTION_ARGS)
static int
bcTruelen(BpChar *arg)
{
char *s = VARDATA_ANY(arg);
int i;
- int len;
! len = VARSIZE_ANY_EXHDR(arg);
! for (i = len - 1; i >= 0; i--)
{
if (s[i] != ' ')
break;
}
return i + 1;
}
--- 624,657 ----
static int
bcTruelen(BpChar *arg)
{
+ const uint32_t spaces = 0x20202020;
+ const int wordsize = sizeof(spaces);
char *s = VARDATA_ANY(arg);
int i;
! i = VARSIZE_ANY_EXHDR(arg) - 1;
!
! /* compare down to an aligned boundary */
! for (; i > 0 && !PointerIsAligned(s + i - (wordsize - 1), uint32_t); i--)
{
if (s[i] != ' ')
+ return i + 1;
+ }
+
+ /* now that we're aligned, compare word at a time */
+ for (; i >= wordsize - 1; i -= wordsize)
+ {
+ if (*(uint32_t *)(s + i - (wordsize - 1)) != spaces)
break;
}
+
+ /* check within the last non-matching word */
+ for (; i >= 0; i--)
+ {
+ if (s[i] != ' ')
+ break;
+ }
+
return i + 1;
}
From | Date | Subject | |
---|---|---|---|
Next Message | Robert Haas | 2009-06-24 02:25:20 | Re: [PATCH] backend: compare word-at-a-time in bcTruelen |
Previous Message | Peter Eisentraut | 2009-06-23 23:28:43 | that picksplit debug message again |