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