summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2017-01-30 00:04:40 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2017-02-01 17:25:21 -0800
commitf07b1b95dfc47ab9cc492f07aa485e4ffb1cb9dc (patch)
treef0b94579029aff4d30f97d534d67587b127f4303
parent20ca6364bd25c89fcded930dc63b7b6a67825b65 (diff)
downloadgrep-f07b1b95dfc47ab9cc492f07aa485e4ffb1cb9dc.tar.gz
grep: tune to avoid memchr2 sometimes
Problem noted by Norihiro Tanaka in: http://lists.gnu.org/archive/html/grep-devel/2017-01/msg00027.html Although not enough to restore all the previous performance in the case he noted, it helps significantly. * src/kwset.c (memchr_kwset): Bring back small_heuristic, in a somewhat different form.
-rw-r--r--src/kwset.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/src/kwset.c b/src/kwset.c
index 3be5c427..cdfe8d1c 100644
--- a/src/kwset.c
+++ b/src/kwset.c
@@ -639,12 +639,26 @@ bm_delta2_search (char const **tpp, char const *ep, char const *sp,
static char const *
memchr_kwset (char const *s, ptrdiff_t n, kwset_t kwset)
{
- if (0 <= kwset->gc1help)
- return memchr2 (s, kwset->gc1, kwset->gc1help, n);
char const *slim = s + n;
- for (; s < slim; s++)
- if (U(kwset->trans[U(*s)]) == kwset->gc1)
- return s;
+ if (kwset->gc1help < 0)
+ {
+ for (; s < slim; s++)
+ if (kwset->next[U(*s)])
+ return s;
+ }
+ else
+ {
+ int small_heuristic = 2;
+ size_t small_bytes = small_heuristic * sizeof (unsigned long int);
+ while (s < slim)
+ {
+ if (kwset->next[U(*s)])
+ return s;
+ s++;
+ if ((uintptr_t) s % small_bytes == 0)
+ return memchr2 (s, kwset->gc1, kwset->gc1help, slim - s);
+ }
+ }
return NULL;
}