Optimize first-character loop of strstr, strcasestr and memmem.

This commit is contained in:
Maxim Kuvyrkov 2012-05-29 00:04:12 -07:00
parent 21ad055803
commit 20a71f2c8a
2 changed files with 20 additions and 1 deletions

View File

@ -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> 2012-08-21 Roland McGrath <roland@hack.frob.com>
* csu/elf-init.c (__libc_csu_irel): Function removed. * csu/elf-init.c (__libc_csu_irel): Function removed.

View File

@ -258,14 +258,27 @@ two_way_short_needle (const unsigned char *haystack, size_t haystack_len,
} }
else 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 /* The two halves of needle are distinct; no extra memory is
required, and any mismatch results in a maximal shift. */ required, and any mismatch results in a maximal shift. */
period = MAX (suffix, needle_len - suffix) + 1; period = MAX (suffix, needle_len - suffix) + 1;
j = 0; j = 0;
while (AVAILABLE (haystack, haystack_len, j, needle_len)) 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. */ /* Scan for matches in right half. */
i = suffix; i = suffix + 1;
while (i < needle_len && (CANON_ELEMENT (needle[i]) while (i < needle_len && (CANON_ELEMENT (needle[i])
== CANON_ELEMENT (haystack[i + j]))) == CANON_ELEMENT (haystack[i + j])))
++i; ++i;