Thu, 23 Feb 2017 15:25:26 +0100
further performance tweaks to sstrstr() function
ucx/string.c | file | annotate | diff | comparison | revisions |
1.1 --- a/ucx/string.c Thu Feb 23 14:30:12 2017 +0100 1.2 +++ b/ucx/string.c Thu Feb 23 15:25:26 2017 +0100 1.3 @@ -176,21 +176,13 @@ 1.4 return n; 1.5 } 1.6 1.7 -typedef size_t(*prefix_table_rfun)(void*,size_t); 1.8 -typedef void(*prefix_table_wfun)(void*,size_t,size_t); 1.9 +#define ptable_r(dest, useheap, ptable, index) (dest = useheap ? \ 1.10 + ((size_t*)ptable)[index] : (size_t) ((uint8_t*)ptable)[index]) 1.11 1.12 -static size_t s_prefix_table_r(void* table, size_t index) { 1.13 - return (size_t) ((uint8_t*)table)[index]; 1.14 -} 1.15 -static void s_prefix_table_w(void* table, size_t index, size_t value) { 1.16 - ((uint8_t*)table)[index] = (uint8_t) value; 1.17 -} 1.18 -static size_t h_prefix_table_r(void* table, size_t index) { 1.19 - return ((size_t*)table)[index]; 1.20 -} 1.21 -static void h_prefix_table_w(void* table, size_t index, size_t value) { 1.22 - ((size_t*)table)[index] = value; 1.23 -} 1.24 +#define ptable_w(useheap, ptable, index, src) do {\ 1.25 + if (!useheap) ((uint8_t*)ptable)[index] = (uint8_t) src;\ 1.26 + else ((size_t*)ptable)[index] = src;\ 1.27 + } while (0); 1.28 1.29 sstr_t sstrstr(sstr_t string, sstr_t match) { 1.30 if (match.length == 0) { 1.31 @@ -212,39 +204,30 @@ 1.32 static uint8_t s_prefix_table[256]; 1.33 1.34 /* check pattern length and use appropriate prefix table */ 1.35 - register void* ptable; 1.36 - prefix_table_rfun ptable_r; 1.37 - prefix_table_wfun ptable_w; 1.38 - if (match.length > 255) { 1.39 - /* pattern exceeds static prefix table, allocate on the heap */ 1.40 - ptable = calloc(match.length+1, sizeof(size_t)); 1.41 - ptable_r = h_prefix_table_r; 1.42 - ptable_w = h_prefix_table_w; 1.43 - } else { 1.44 - ptable = s_prefix_table; 1.45 - ptable_r = s_prefix_table_r; 1.46 - ptable_w = s_prefix_table_w; 1.47 - } 1.48 + /* if the pattern exceeds static prefix table, allocate on the heap */ 1.49 + register int useheap = match.length > 255; 1.50 + register void* ptable = useheap ? 1.51 + calloc(match.length+1, sizeof(size_t)): s_prefix_table; 1.52 1.53 /* keep counter in registers */ 1.54 register size_t i, j; 1.55 1.56 /* fill prefix table */ 1.57 i = 0; j = 0; 1.58 - ptable_w(ptable, i, j); 1.59 + ptable_w(useheap, ptable, i, j); 1.60 while (i < match.length) { 1.61 while (j >= 1 && match.ptr[j-1] != match.ptr[i]) { 1.62 - j = ptable_r(ptable, j-i); 1.63 + ptable_r(j, useheap, ptable, j-i); 1.64 } 1.65 i++; j++; 1.66 - ptable_w(ptable, i, j); 1.67 + ptable_w(useheap, ptable, i, j); 1.68 } 1.69 1.70 /* search */ 1.71 i = 0; j = 1; 1.72 while (i < string.length) { 1.73 while (j >= 1 && string.ptr[i] != match.ptr[j-1]) { 1.74 - j = ptable_r(ptable, j-1); 1.75 + ptable_r(j, useheap, ptable, j-1); 1.76 } 1.77 i++; j++; 1.78 if (j-1 == match.length) { 1.79 @@ -263,6 +246,9 @@ 1.80 return result; 1.81 } 1.82 1.83 +#undef ptable_r 1.84 +#undef ptable_w 1.85 + 1.86 sstr_t* sstrsplit(sstr_t s, sstr_t d, ssize_t *n) { 1.87 return sstrsplit_a(ucx_default_allocator(), s, d, n); 1.88 }