diff options
author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2016-03-26 19:09:07 +0000 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2016-04-01 10:44:44 -0300 |
commit | 91f3b75f47c9eca3299098c3dcc2f5d9dad320b1 (patch) | |
tree | f00e3a58386999ac44a322211ff74cffcb37df99 /string/string-inlines.c | |
parent | d3496c9f4f27d3009b71be87f6108b4fed7314bd (diff) | |
download | glibc-91f3b75f47c9eca3299098c3dcc2f5d9dad320b1.tar.gz glibc-91f3b75f47c9eca3299098c3dcc2f5d9dad320b1.tar.xz glibc-91f3b75f47c9eca3299098c3dcc2f5d9dad320b1.zip |
Improve generic strspn performance
As for strcspn, this patch improves strspn performance using a much faster algorithm. It first constructs a 256-entry table based on the accept string and then uses it as a lookup table for the input string. 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, i686, and aarch64. * string/strspn.c (strcspn): Rewrite function. * string/bits/string2.h (strspn): Use __builtin_strcspn. (__strspn_c1): Remove inline function. (__strspn_c2): Likewise. (__strspn_c3): Likewise. * string/string-inlines.c [SHLIB_COMPAT(libc, GLIBC_2_1_1, GLIBC_2_24)] (__strspn_c1): Add compatibility symbol. [SHLIB_COMPAT(libc, GLIBC_2_1_1, GLIBC_2_24)] (__strspn_c2): Likewise. [SHLIB_COMPAT(libc, GLIBC_2_1_1, GLIBC_2_24)] (__strspn_c3): Likewise.
Diffstat (limited to 'string/string-inlines.c')
-rw-r--r-- | string/string-inlines.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/string/string-inlines.c b/string/string-inlines.c index 83bdd6c185..754b31530f 100644 --- a/string/string-inlines.c +++ b/string/string-inlines.c @@ -71,4 +71,40 @@ __old_strcspn_c3 (const char *__s, int __reject1, int __reject2, return __result; } compat_symbol (libc, __old_strcspn_c3, __strcspn_c3, GLIBC_2_1_1); + +size_t +__old_strspn_c1 (const char *__s, int __accept) +{ + size_t __result = 0; + /* Please note that __accept never can be '\0'. */ + while (__s[__result] == __accept) + ++__result; + return __result; +} +compat_symbol (libc, __old_strspn_c1, __strspn_c1, GLIBC_2_1_1); + +size_t +__old_strspn_c2 (const char *__s, int __accept1, int __accept2) +{ + size_t __result = 0; + /* Please note that __accept1 and __accept2 never can be '\0'. */ + while (__s[__result] == __accept1 || __s[__result] == __accept2) + ++__result; + return __result; +} +compat_symbol (libc, __old_strspn_c2, __strspn_c2, GLIBC_2_1_1); + +size_t +__old_strspn_c3 (const char *__s, int __accept1, int __accept2, + int __accept3) +{ + size_t __result = 0; + /* Please note that __accept1 to __accept3 never can be '\0'. */ + while (__s[__result] == __accept1 || __s[__result] == __accept2 + || __s[__result] == __accept3) + ++__result; + return __result; +} +compat_symbol (libc, __old_strspn_c3, __strspn_c3, GLIBC_2_1_1); + #endif |