diff options
author | Maxim Kuvyrkov <maxim@codesourcery.com> | 2012-05-29 00:04:12 -0700 |
---|---|---|
committer | Maxim Kuvyrkov <maxim@codesourcery.com> | 2012-08-21 18:07:47 -0700 |
commit | 20a71f2c8ab45b458416422af2eec2b7bc52f66b (patch) | |
tree | e6d068b2b2bd69b9400270a51f4c5879a998607b | |
parent | 21ad055803de5dd03606588753c46fbf8a5863b2 (diff) | |
download | glibc-20a71f2c8ab45b458416422af2eec2b7bc52f66b.tar.gz glibc-20a71f2c8ab45b458416422af2eec2b7bc52f66b.tar.xz glibc-20a71f2c8ab45b458416422af2eec2b7bc52f66b.zip |
Optimize first-character loop of strstr, strcasestr and memmem.
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | string/str-two-way.h | 15 |
2 files changed, 20 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog index c6a780de1e..7c96e02795 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2012-08-21 Maxim Kuvyrkov <maxim@codesourcery.com> + + [BZ #11607] + * string/str-two-way.h (two_way_short_needle): Optimize matching of + the first character. + 2012-08-21 Roland McGrath <roland@hack.frob.com> * csu/elf-init.c (__libc_csu_irel): Function removed. diff --git a/string/str-two-way.h b/string/str-two-way.h index 22e75393dc..e18dc91738 100644 --- a/string/str-two-way.h +++ b/string/str-two-way.h @@ -258,14 +258,27 @@ two_way_short_needle (const unsigned char *haystack, size_t haystack_len, } else { + /* The comparison always starts from needle[suffix], so cache it + and use an optimized first-character loop. */ + unsigned char needle_suffix = CANON_ELEMENT (needle[suffix]); + /* The two halves of needle are distinct; no extra memory is required, and any mismatch results in a maximal shift. */ period = MAX (suffix, needle_len - suffix) + 1; j = 0; while (AVAILABLE (haystack, haystack_len, j, needle_len)) { + /* TODO: The first-character loop can be sped up by adapting + longword-at-a-time implementation of memchr/strchr. */ + if (needle_suffix + != CANON_ELEMENT (haystack[suffix + j])) + { + ++j; + continue; + } + /* Scan for matches in right half. */ - i = suffix; + i = suffix + 1; while (i < needle_len && (CANON_ELEMENT (needle[i]) == CANON_ELEMENT (haystack[i + j]))) ++i; |