aboutsummaryrefslogtreecommitdiff
path: root/string
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2016-03-27 13:33:56 +0000
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2016-04-01 10:44:45 -0300
commit282b71f07eb5e24ddf1308f92c37cb42f7c7d86b (patch)
treed6d79415c05a70ebf19c604c702b3dc96084d551 /string
parent91f3b75f47c9eca3299098c3dcc2f5d9dad320b1 (diff)
downloadglibc-282b71f07eb5e24ddf1308f92c37cb42f7c7d86b.zip
glibc-282b71f07eb5e24ddf1308f92c37cb42f7c7d86b.tar.gz
glibc-282b71f07eb5e24ddf1308f92c37cb42f7c7d86b.tar.bz2
Improve generic strpbrk performance
With now a faster strcspn implementation, it is faster to just use it with some return tests than reimplementing strpbrk itself. As for strcspn optimization, it is generally at least 10 times faster than the existing implementation on bench-strspn on a few AArch64 implementations. Also the string/bits/string2.h inlines make no longer sense, as current implementation will already implement most of the optimizations. Tested on x86_64, i386, and aarch64. * string/strpbrk.c (strpbrk): Rewrite function. * string/bits/string2.h (strpbrk): Use __builtin_strpbrk. (__strpbrk_c2): Likewise. (__strpbrk_c3): Likewise. * string/string-inlines.c [SHLIB_COMPAT(libc, GLIBC_2_1_1, GLIBC_2_24)] (__strpbrk_c2): Likewise. [SHLIB_COMPAT(libc, GLIBC_2_1_1, GLIBC_2_24)] (__strpbrk_c3): Likewise.
Diffstat (limited to 'string')
-rw-r--r--string/bits/string2.h61
-rw-r--r--string/string-inlines.c21
-rw-r--r--string/strpbrk.c12
3 files changed, 26 insertions, 68 deletions
diff --git a/string/bits/string2.h b/string/bits/string2.h
index 75a66a1..5a138dc 100644
--- a/string/bits/string2.h
+++ b/string/bits/string2.h
@@ -922,65 +922,10 @@ __stpcpy_small (char *__dest,
/* Find the first occurrence in S of any character in ACCEPT. */
-#if !defined _HAVE_STRING_ARCH_strpbrk || defined _FORCE_INLINES
-# ifndef _HAVE_STRING_ARCH_strpbrk
-# if __GNUC_PREREQ (3, 2)
-# define strpbrk(s, accept) \
- __extension__ \
- ({ char __a0, __a1, __a2; \
- (__builtin_constant_p (accept) && __string2_1bptr_p (accept) \
- ? ((__builtin_constant_p (s) && __string2_1bptr_p (s)) \
- ? __builtin_strpbrk (s, accept) \
- : ((__a0 = ((const char *) (accept))[0], __a0 == '\0') \
- ? ((void) (s), (char *) NULL) \
- : ((__a1 = ((const char *) (accept))[1], __a1 == '\0') \
- ? __builtin_strchr (s, __a0) \
- : ((__a2 = ((const char *) (accept))[2], __a2 == '\0') \
- ? __strpbrk_c2 (s, __a0, __a1) \
- : (((const char *) (accept))[3] == '\0' \
- ? __strpbrk_c3 (s, __a0, __a1, __a2) \
- : __builtin_strpbrk (s, accept)))))) \
- : __builtin_strpbrk (s, accept)); })
-# else
-# define strpbrk(s, accept) \
- __extension__ \
- ({ char __a0, __a1, __a2; \
- (__builtin_constant_p (accept) && __string2_1bptr_p (accept) \
- ? ((__a0 = ((const char *) (accept))[0], __a0 == '\0') \
- ? ((void) (s), (char *) NULL) \
- : ((__a1 = ((const char *) (accept))[1], __a1 == '\0') \
- ? strchr (s, __a0) \
- : ((__a2 = ((const char *) (accept))[2], __a2 == '\0') \
- ? __strpbrk_c2 (s, __a0, __a1) \
- : (((const char *) (accept))[3] == '\0' \
- ? __strpbrk_c3 (s, __a0, __a1, __a2) \
- : strpbrk (s, accept))))) \
- : strpbrk (s, accept)); })
-# endif
+#ifndef _HAVE_STRING_ARCH_strpbrk
+# if __GNUC_PREREQ (3, 2)
+# define strpbrk(s, accept) __builtin_strpbrk (s, accept)
# endif
-
-__STRING_INLINE char *__strpbrk_c2 (const char *__s, int __accept1,
- int __accept2);
-__STRING_INLINE char *
-__strpbrk_c2 (const char *__s, int __accept1, int __accept2)
-{
- /* Please note that __accept1 and __accept2 never can be '\0'. */
- while (*__s != '\0' && *__s != __accept1 && *__s != __accept2)
- ++__s;
- return *__s == '\0' ? NULL : (char *) (size_t) __s;
-}
-
-__STRING_INLINE char *__strpbrk_c3 (const char *__s, int __accept1,
- int __accept2, int __accept3);
-__STRING_INLINE char *
-__strpbrk_c3 (const char *__s, int __accept1, int __accept2, int __accept3)
-{
- /* Please note that __accept1 to __accept3 never can be '\0'. */
- while (*__s != '\0' && *__s != __accept1 && *__s != __accept2
- && *__s != __accept3)
- ++__s;
- return *__s == '\0' ? NULL : (char *) (size_t) __s;
-}
#endif
diff --git a/string/string-inlines.c b/string/string-inlines.c
index 754b315..0648376 100644
--- a/string/string-inlines.c
+++ b/string/string-inlines.c
@@ -107,4 +107,25 @@ __old_strspn_c3 (const char *__s, int __accept1, int __accept2,
}
compat_symbol (libc, __old_strspn_c3, __strspn_c3, GLIBC_2_1_1);
+char *
+__strpbrk_c2 (const char *__s, int __accept1, int __accept2)
+{
+ /* Please note that __accept1 and __accept2 never can be '\0'. */
+ while (*__s != '\0' && *__s != __accept1 && *__s != __accept2)
+ ++__s;
+ return *__s == '\0' ? NULL : (char *) (size_t) __s;
+}
+compat_symbol (libc, __old_strpbrk_c2, __strpbrk_c2, GLIBC_2_1_1);
+
+char *
+__strpbrk_c3 (const char *__s, int __accept1, int __accept2, int __accept3)
+{
+ /* Please note that __accept1 to __accept3 never can be '\0'. */
+ while (*__s != '\0' && *__s != __accept1 && *__s != __accept2
+ && *__s != __accept3)
+ ++__s;
+ return *__s == '\0' ? NULL : (char *) (size_t) __s;
+}
+compat_symbol (libc, __old_strpbrk_c3, __strpbrk_c3, GLIBC_2_1_1);
+
#endif
diff --git a/string/strpbrk.c b/string/strpbrk.c
index fddd473..1ede719 100644
--- a/string/strpbrk.c
+++ b/string/strpbrk.c
@@ -27,15 +27,7 @@
char *
STRPBRK (const char *s, const char *accept)
{
- while (*s != '\0')
- {
- const char *a = accept;
- while (*a != '\0')
- if (*a++ == *s)
- return (char *) s;
- ++s;
- }
-
- return NULL;
+ s += strcspn (s, accept);
+ return *s ? (char *)s : NULL;
}
libc_hidden_builtin_def (strpbrk)