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 <j...@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;
  }
  

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to