aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxim Kuvyrkov <maxim@codesourcery.com>2012-05-29 00:04:12 -0700
committerMaxim Kuvyrkov <maxim@codesourcery.com>2012-08-21 18:07:47 -0700
commit20a71f2c8ab45b458416422af2eec2b7bc52f66b (patch)
treee6d068b2b2bd69b9400270a51f4c5879a998607b
parent21ad055803de5dd03606588753c46fbf8a5863b2 (diff)
downloadglibc-20a71f2c8ab45b458416422af2eec2b7bc52f66b.tar
glibc-20a71f2c8ab45b458416422af2eec2b7bc52f66b.tar.gz
glibc-20a71f2c8ab45b458416422af2eec2b7bc52f66b.tar.bz2
glibc-20a71f2c8ab45b458416422af2eec2b7bc52f66b.zip
Optimize first-character loop of strstr, strcasestr and memmem.
-rw-r--r--ChangeLog6
-rw-r--r--string/str-two-way.h15
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;