Optimize first-character loop of strstr, strcasestr and memmem.
authorMaxim Kuvyrkov <maxim@codesourcery.com>
Tue, 29 May 2012 07:04:12 +0000 (00:04 -0700)
committerMaxim Kuvyrkov <maxim@codesourcery.com>
Wed, 22 Aug 2012 01:07:47 +0000 (18:07 -0700)
ChangeLog
string/str-two-way.h

index c6a780d..7c96e02 100644 (file)
--- 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.
index 22e7539..e18dc91 100644 (file)
@@ -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;