[PATCH] backend: compare word-at-a-time in bcTruelen

Поиск
Список
Период
Сортировка
От Jeremy Kerr
Тема [PATCH] backend: compare word-at-a-time in bcTruelen
Дата
Msg-id 1245805503.62025.32374376046.1.gpush@pingu
обсуждение исходный текст
Ответ на Re: [PATCH] backend: compare word-at-a-time in bcTruelen  (Jeremy Kerr <jk@ozlabs.org>)
Ответы Re: [PATCH] backend: compare word-at-a-time in bcTruelen  (Robert Haas <robertmhaas@gmail.com>)
Список 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@ozlabs.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; } 


В списке pgsql-hackers по дате отправления:

Предыдущее
От: Peter Eisentraut
Дата:
Сообщение: that picksplit debug message again
Следующее
От: Robert Haas
Дата:
Сообщение: Re: [PATCH] backend: compare word-at-a-time in bcTruelen