Skip to content

Commit

Permalink
Add performance tests for strstr and strcasestr.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ulrich Drepper committed Jul 24, 2010
1 parent b893425 commit dbc676d
Show file tree
Hide file tree
Showing 6 changed files with 407 additions and 6 deletions.
8 changes: 8 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
2010-07-23 Ulrich Drepper <drepper@redhat.com>

* string/test-strcasestr.c: New file.
* string/test-strstr.c: New file.
* string/Makefile (strop-tests): Add strstr and strcasestr.
* string/str-two-way.h: Don't undefine MAX.
* string/strcasestr.c: Don't define alias if NO_ALIAS is defined.

2010-07-21 Andreas Schwab <schwab@redhat.com>

* sysdeps/i386/i686/multiarch/Makefile (sysdep_routines): Add
Expand Down
7 changes: 4 additions & 3 deletions string/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (C) 1991-2002, 2005-2008, 2009 Free Software Foundation, Inc.
# Copyright (C) 1991-2002, 2005-2008, 2009, 2010 Free Software Foundation, Inc.
# This file is part of the GNU C Library.

# The GNU C Library is free software; you can redistribute it and/or
Expand Down Expand Up @@ -36,7 +36,7 @@ routines := strcat strchr strcmp strcoll strcpy strcspn \
memccpy memcpy wordcopy strsep strcasestr \
swab strfry memfrob memmem rawmemchr strchrnul \
$(addprefix argz-,append count create ctsep next \
delete extract insert stringify \
delete extract insert stringify \
addsep replace) \
envz basename \
strcoll_l strxfrm_l string-inlines memrchr \
Expand All @@ -48,7 +48,8 @@ o-objects.ob := memcpy.o memset.o memchr.o

strop-tests := memchr memcmp memcpy memmove mempcpy memset memccpy \
stpcpy stpncpy strcat strchr strcmp strcpy strcspn \
strlen strncmp strncpy strpbrk strrchr strspn memmem
strlen strncmp strncpy strpbrk strrchr strspn memmem \
strstr strcasestr
tests := tester inl-tester noinl-tester testcopy test-ffs \
tst-strlen stratcliff tst-svc tst-inlcall \
bug-strncat1 bug-strspn1 bug-strpbrk1 tst-bswap \
Expand Down
3 changes: 1 addition & 2 deletions string/str-two-way.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* Byte-wise substring search, using the Two-Way algorithm.
Copyright (C) 2008 Free Software Foundation, Inc.
Copyright (C) 2008, 2010 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Eric Blake <ebb9@byu.net>, 2008.
Expand Down Expand Up @@ -426,5 +426,4 @@ two_way_long_needle (const unsigned char *haystack, size_t haystack_len,
#undef AVAILABLE
#undef CANON_ELEMENT
#undef CMP_FUNC
#undef MAX
#undef RETURN_TYPE
4 changes: 3 additions & 1 deletion string/strcasestr.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* Return the offset of one string within another.
Copyright (C) 1994, 1996-2000, 2004, 2008, 2009
Copyright (C) 1994, 1996-2000, 2004, 2008, 2009, 2010
Free Software Foundation, Inc.
This file is part of the GNU C Library.
Expand Down Expand Up @@ -103,4 +103,6 @@ STRCASESTR (const char *haystack_start, const char *needle_start)

#undef LONG_NEEDLE_THRESHOLD

#ifndef NO_ALIAS
weak_alias (__strcasestr, strcasestr)
#endif
197 changes: 197 additions & 0 deletions string/test-strcasestr.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
/* Test and measure strcasestr functions.
Copyright (C) 2010 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Ulrich Drepper <drepper@redhat.com>, 2010.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */

#define TEST_MAIN
#include "test-string.h"


#define STRCASESTR simple_strcasestr
#define NO_ALIAS
#define __strncasecmp strncasecmp
#include "strcasestr.c"


static char *
stupid_strcasestr (const char *s1, const char *s2)
{
ssize_t s1len = strlen (s1);
ssize_t s2len = strlen (s2);

if (s2len > s1len)
return NULL;

for (ssize_t i = 0; i <= s1len - s2len; ++i)
{
size_t j;
for (j = 0; j < s2len; ++j)
if (tolower (s1[i + j]) != tolower (s2[j]))
break;
if (j == s2len)
return (char *) s1 + i;
}

return NULL;
}


typedef char *(*proto_t) (const char *, const char *);

IMPL (stupid_strcasestr, 0)
IMPL (simple_strcasestr, 0)
IMPL (strcasestr, 1)


static void
do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result)
{
char *result = CALL (impl, s1, s2);
if (result != exp_result)
{
error (0, 0, "Wrong result in function %s %s %s", impl->name,
result, exp_result);
ret = 1;
return;
}

if (HP_TIMING_AVAIL)
{
hp_timing_t start __attribute ((unused));
hp_timing_t stop __attribute ((unused));
hp_timing_t best_time = ~(hp_timing_t) 0;
size_t i;

for (i = 0; i < 32; ++i)
{
HP_TIMING_NOW (start);
CALL (impl, s1, s2);
HP_TIMING_NOW (stop);
HP_TIMING_BEST (best_time, start, stop);
}

printf ("\t%zd", (size_t) best_time);
}
}


static void
do_test (size_t align1, size_t align2, size_t len1, size_t len2,
int fail)
{
char *s1 = (char *) (buf1 + align1);
char *s2 = (char *) (buf2 + align2);

static const char d[] = "1234567890abcdef";
#define dl (sizeof (d) - 1)
char *ss2 = s2;
for (size_t l = len2; l > 0; l = l > dl ? l - dl : 0)
{
size_t t = l > dl ? dl : l;
ss2 = mempcpy (ss2, d, t);
}
s2[len2] = '\0';

if (fail)
{
char *ss1 = s1;
for (size_t l = len1; l > 0; l = l > dl ? l - dl : 0)
{
size_t t = l > dl ? dl : l;
memcpy (ss1, d, t);
++ss1[len2 > 7 ? 7 : len2 - 1];
ss1 += t;
}
}
else
{
memset (s1, '0', len1);
for (size_t i = 0; i < len2; ++i)
s1[len1 - len2 + i] = toupper (s2[i]);
}
s1[len1] = '\0';

if (HP_TIMING_AVAIL)
printf ("Length %4zd/%zd, alignment %2zd/%2zd, %s:",
len1, len2, align1, align2, fail ? "fail" : "found");

FOR_EACH_IMPL (impl, 0)
do_one_test (impl, s1, s2, fail ? NULL : s1 + len1 - len2);

if (HP_TIMING_AVAIL)
putchar ('\n');
}


static int
test_main (void)
{
test_init ();

printf ("%23s", "");
FOR_EACH_IMPL (impl, 0)
printf ("\t%s", impl->name);
putchar ('\n');

for (size_t klen = 2; klen < 32; ++klen)
for (size_t hlen = 2 * klen; hlen < 16 * klen; hlen += klen)
{
do_test (0, 0, hlen, klen, 0);
do_test (0, 0, hlen, klen, 1);
do_test (0, 3, hlen, klen, 0);
do_test (0, 3, hlen, klen, 1);
do_test (0, 9, hlen, klen, 0);
do_test (0, 9, hlen, klen, 1);
do_test (0, 15, hlen, klen, 0);
do_test (0, 15, hlen, klen, 1);

do_test (3, 0, hlen, klen, 0);
do_test (3, 0, hlen, klen, 1);
do_test (3, 3, hlen, klen, 0);
do_test (3, 3, hlen, klen, 1);
do_test (3, 9, hlen, klen, 0);
do_test (3, 9, hlen, klen, 1);
do_test (3, 15, hlen, klen, 0);
do_test (3, 15, hlen, klen, 1);

do_test (9, 0, hlen, klen, 0);
do_test (9, 0, hlen, klen, 1);
do_test (9, 3, hlen, klen, 0);
do_test (9, 3, hlen, klen, 1);
do_test (9, 9, hlen, klen, 0);
do_test (9, 9, hlen, klen, 1);
do_test (9, 15, hlen, klen, 0);
do_test (9, 15, hlen, klen, 1);

do_test (15, 0, hlen, klen, 0);
do_test (15, 0, hlen, klen, 1);
do_test (15, 3, hlen, klen, 0);
do_test (15, 3, hlen, klen, 1);
do_test (15, 9, hlen, klen, 0);
do_test (15, 9, hlen, klen, 1);
do_test (15, 15, hlen, klen, 0);
do_test (15, 15, hlen, klen, 1);
}

do_test (0, 0, page_size - 1, 16, 0);
do_test (0, 0, page_size - 1, 16, 1);

return ret;
}

#include "../test-skeleton.c"
Loading

0 comments on commit dbc676d

Please sign in to comment.