summaryrefslogtreecommitdiff
path: root/string
diff options
context:
space:
mode:
authorWilco Dijkstra <wdijkstr@arm.com>2015-08-19 16:28:21 +0100
committerWilco Dijkstra <wdijkstr@arm.com>2015-08-19 16:32:12 +0100
commit48497aba8ec7887dd505e37aa95ab52348fa8cb2 (patch)
treede869b831f1e1ab25f697b57929c1a5af255b431 /string
parenta08e80d1143f6b0386d5bc8cc7b8ed576091dbf3 (diff)
downloadglibc-48497aba8ec7887dd505e37aa95ab52348fa8cb2.tar.gz
Improve stpncpy performance by using __strnlen/memcpy/memset rather than a
byte loop. Performance on bench-stpncpy is ~2x faster on average.
Diffstat (limited to 'string')
-rw-r--r--string/stpncpy.c59
1 files changed, 5 insertions, 54 deletions
diff --git a/string/stpncpy.c b/string/stpncpy.c
index eb65a5f46f..4c3351ba01 100644
--- a/string/stpncpy.c
+++ b/string/stpncpy.c
@@ -15,8 +15,6 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-/* This is almost copied from strncpy.c, written by Torbjorn Granlund. */
-
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
@@ -41,59 +39,12 @@ weak_alias (__stpncpy, stpncpy)
char *
STPNCPY (char *dest, const char *src, size_t n)
{
- char c;
- char *s = dest;
-
- if (n >= 4)
- {
- size_t n4 = n >> 2;
-
- for (;;)
- {
- c = *src++;
- *dest++ = c;
- if (c == '\0')
- break;
- c = *src++;
- *dest++ = c;
- if (c == '\0')
- break;
- c = *src++;
- *dest++ = c;
- if (c == '\0')
- break;
- c = *src++;
- *dest++ = c;
- if (c == '\0')
- break;
- if (--n4 == 0)
- goto last_chars;
- }
- n -= dest - s;
- goto zero_fill;
- }
-
- last_chars:
- n &= 3;
- if (n == 0)
+ size_t size = __strnlen (src, n);
+ memcpy (dest, src, size);
+ dest += size;
+ if (size == n)
return dest;
-
- for (;;)
- {
- c = *src++;
- --n;
- *dest++ = c;
- if (c == '\0')
- break;
- if (n == 0)
- return dest;
- }
-
- zero_fill:
- while (n-- > 0)
- dest[n] = '\0';
-
- return dest - 1;
+ return memset (dest, '\0', n - size);
}
#ifdef weak_alias
libc_hidden_def (__stpncpy)