# HG changeset patch # User Mike Becker # Date 1487859926 -3600 # Node ID 5ba9de6361ff79c4ee6bfe0a9fddd9dcd0569d71 # Parent ffc6d09103427b72ab19b6165c6d83fddd9c9fea further performance tweaks to sstrstr() function diff -r ffc6d0910342 -r 5ba9de6361ff ucx/string.c --- a/ucx/string.c Thu Feb 23 14:30:12 2017 +0100 +++ b/ucx/string.c Thu Feb 23 15:25:26 2017 +0100 @@ -176,21 +176,13 @@ return n; } -typedef size_t(*prefix_table_rfun)(void*,size_t); -typedef void(*prefix_table_wfun)(void*,size_t,size_t); +#define ptable_r(dest, useheap, ptable, index) (dest = useheap ? \ + ((size_t*)ptable)[index] : (size_t) ((uint8_t*)ptable)[index]) -static size_t s_prefix_table_r(void* table, size_t index) { - return (size_t) ((uint8_t*)table)[index]; -} -static void s_prefix_table_w(void* table, size_t index, size_t value) { - ((uint8_t*)table)[index] = (uint8_t) value; -} -static size_t h_prefix_table_r(void* table, size_t index) { - return ((size_t*)table)[index]; -} -static void h_prefix_table_w(void* table, size_t index, size_t value) { - ((size_t*)table)[index] = value; -} +#define ptable_w(useheap, ptable, index, src) do {\ + if (!useheap) ((uint8_t*)ptable)[index] = (uint8_t) src;\ + else ((size_t*)ptable)[index] = src;\ + } while (0); sstr_t sstrstr(sstr_t string, sstr_t match) { if (match.length == 0) { @@ -212,39 +204,30 @@ static uint8_t s_prefix_table[256]; /* check pattern length and use appropriate prefix table */ - register void* ptable; - prefix_table_rfun ptable_r; - prefix_table_wfun ptable_w; - if (match.length > 255) { - /* pattern exceeds static prefix table, allocate on the heap */ - ptable = calloc(match.length+1, sizeof(size_t)); - ptable_r = h_prefix_table_r; - ptable_w = h_prefix_table_w; - } else { - ptable = s_prefix_table; - ptable_r = s_prefix_table_r; - ptable_w = s_prefix_table_w; - } + /* if the pattern exceeds static prefix table, allocate on the heap */ + register int useheap = match.length > 255; + register void* ptable = useheap ? + calloc(match.length+1, sizeof(size_t)): s_prefix_table; /* keep counter in registers */ register size_t i, j; /* fill prefix table */ i = 0; j = 0; - ptable_w(ptable, i, j); + ptable_w(useheap, ptable, i, j); while (i < match.length) { while (j >= 1 && match.ptr[j-1] != match.ptr[i]) { - j = ptable_r(ptable, j-i); + ptable_r(j, useheap, ptable, j-i); } i++; j++; - ptable_w(ptable, i, j); + ptable_w(useheap, ptable, i, j); } /* search */ i = 0; j = 1; while (i < string.length) { while (j >= 1 && string.ptr[i] != match.ptr[j-1]) { - j = ptable_r(ptable, j-1); + ptable_r(j, useheap, ptable, j-1); } i++; j++; if (j-1 == match.length) { @@ -263,6 +246,9 @@ return result; } +#undef ptable_r +#undef ptable_w + sstr_t* sstrsplit(sstr_t s, sstr_t d, ssize_t *n) { return sstrsplit_a(ucx_default_allocator(), s, d, n); }