diff options
author | Wilco Dijkstra <wdijkstr@arm.com> | 2015-08-05 15:15:28 +0100 |
---|---|---|
committer | Wilco Dijkstra <wdijkstr@arm.com> | 2015-08-05 16:24:02 +0100 |
commit | f6482cf29d3094ca9688be59802353014c528959 (patch) | |
tree | 11e8c2855b92cb90ce2a16ad55151c60e8d6962f | |
parent | 7b1c56e4834aa3b139fea39ded64a7e901be89a2 (diff) | |
download | glibc-f6482cf29d3094ca9688be59802353014c528959.tar.gz |
This patch improves strncpy performance by using strnlen/memcpy rather than a byte loop. Performance
on bench-strncpy is 1.9-2.1x faster on average. I tried several variations, and using a tailcall and
calling memset conditionally gave the best overall results.
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | string/strncpy.c | 59 |
2 files changed, 10 insertions, 54 deletions
@@ -1,5 +1,10 @@ 2015-08-05 Wilco Dijkstra <wdijkstr@arm.com> + * string/strncpy.c (strncpy): + Improve performance by using __strnlen/memcpy. + +2015-08-05 Wilco Dijkstra <wdijkstr@arm.com> + * sysdeps/aarch64/fpu/feenablxcpt.c (feenableexcept): Optimize to avoid an unnecessary FPCR read. diff --git a/string/strncpy.c b/string/strncpy.c index 37af5aaad0..d464bbb5a6 100644 --- a/string/strncpy.c +++ b/string/strncpy.c @@ -16,68 +16,19 @@ <http://www.gnu.org/licenses/>. */ #include <string.h> -#include <memcopy.h> #undef strncpy #ifndef STRNCPY -#define STRNCPY strncpy + #define STRNCPY strncpy #endif char * STRNCPY (char *s1, const char *s2, size_t n) { - char c; - char *s = s1; - - --s1; - - if (n >= 4) - { - size_t n4 = n >> 2; - - for (;;) - { - c = *s2++; - *++s1 = c; - if (c == '\0') - break; - c = *s2++; - *++s1 = c; - if (c == '\0') - break; - c = *s2++; - *++s1 = c; - if (c == '\0') - break; - c = *s2++; - *++s1 = c; - if (c == '\0') - break; - if (--n4 == 0) - goto last_chars; - } - s1++; - n = n - (s1 - s); - memset (s1, '\0', n); - return s; - } - - last_chars: - n &= 3; - if (n == 0) - return s; - - do - { - c = *s2++; - *++s1 = c; - if (--n == 0) - return s; - } - while (c != '\0'); - - memset (s1 + 1, '\0', n); - return s; + size_t size = __strnlen (s2, n); + if (size != n) + memset (s1 + size, '\0', n - size); + return memcpy (s1, s2, size); } libc_hidden_builtin_def (strncpy) |