Tuesday, June 30, 2020

strlcpy version speed tests?

#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;
}
I made a couple different versions if anybody is interested!
-Luke

No comments:

Post a Comment