I made a couple different versions if anybody is interested! -Luke
#include <unistd.h> #include <stdlib.h> #include <string.h> #include <stdio.h> #include <err.h> #include <sys/param.h>
/* cc strlcpy_test.c -pipe -O2 -o strlcpy_test && ./strlcpy_testfast */ /* * Copy string src to buffer dst of size dsize. At most dsize-1 * chars will be copied. Always NUL terminates (unless dsize == 0). * Returns strlen(src); if retval >= dsize, truncation occurred. */ static size_t strlcpy0(char *dst, const char *src, size_t dsize) { const char *osrc = src; size_t nleft = dsize; /* Copy as many bytes as will fit. */ if (nleft != 0) { while (--nleft != 0) { if ((*dst++ = *src++) == '\0') break; } } /* Not enough room in dst, add NUL and traverse rest of src. */ if (nleft == 0) { if (dsize != 0) *dst = '\0'; /* NUL-terminate dst */ while (*src++) ; } return(src - osrc - 1); /* count does not include NUL */ } static size_t strlcpy3(char *dst, const char *src, size_t dsize) { const char *osrc = src; size_t nleft = dsize; if (nleft != 0) { /* Copy as many bytes as will fit. */ while (--nleft != 0) if ((*dst++ = *src++) == '\0') return(src - osrc - 1); *dst = '\0'; } /* Not enough room in dst, traverse rest of src. */ while (*src++) ; return(src - osrc - 1); /* count does not include NUL */ } static size_t strlcpy4(char dst[], const char src[], size_t dsize) { const char *osrc = src; size_t nleft = dsize; if (nleft != 0) { if (--nleft == 0) { *dst = '\0'; if (*src == '\0') return 0; goto strlcpy_jump; } /* Copy as many bytes as will fit. */ if ((*dst = *src) == '\0') return 0; while (--nleft != 0) if ((*++dst = *++src) == '\0') return(src - osrc); dst[1] = '\0'; /* NUL-terminate dst */ } else if (*src == '\0') return 0; strlcpy_jump: /* Not enough room in dst, traverse rest of src. */ while (*++src) ; return(src - osrc); /* count does not include NUL */ } int main() { long double cpu_time_used; size_t y; struct timespec tv_start, tv_end; char *buffer, *buffer2; size_t n = 50000; size_t m = n + 500; buffer = malloc(m); if (buffer == NULL) err(1, "malloc"); buffer2 = malloc(n); if (buffer2 == NULL) err(1, "malloc"); /* no intermediate '\0' */ for (y = 0; y < m; ++y) buffer[y] = arc4random_uniform(255) + 1; buffer[m - 1] = '\0'; clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tv_start); strlcpy(buffer2, buffer, n); clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tv_end); cpu_time_used = (long double) (tv_end.tv_sec - tv_start.tv_sec) + (long double) (tv_end.tv_nsec - tv_start.tv_nsec) / (long double) 1000000000; printf("\n\nstrlcpy\n"); printf("time = %.9Lf\n\n\n", cpu_time_used); clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tv_start); strlcpy0(buffer2, buffer, n); clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tv_end); cpu_time_used = (long double) (tv_end.tv_sec - tv_start.tv_sec) + (long double) (tv_end.tv_nsec - tv_start.tv_nsec) / (long double) 1000000000; printf("\n\nstrlcpy0\n"); printf("time = %.9Lf\n\n\n", cpu_time_used); clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tv_start); strlcpy3(buffer2, buffer, n); clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tv_end); cpu_time_used = (long double) (tv_end.tv_sec - tv_start.tv_sec) + (long double) (tv_end.tv_nsec - tv_start.tv_nsec) / (long double) 1000000000; printf("\n\nstrlcpy3 \n"); printf("time = %.9Lf\n\n\n", cpu_time_used); clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tv_start); strlcpy4(buffer2, buffer, n); clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tv_end); cpu_time_used = (long double) (tv_end.tv_sec - tv_start.tv_sec) + (long double) (tv_end.tv_nsec - tv_start.tv_nsec) / (long double) 1000000000; printf("\n\nstrlcpy4 \n"); printf("time = %.9Lf\n\n\n", cpu_time_used); return 0; }