Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 21 Apr 2015 17:52:23 +0000
From:      bugzilla-noreply@freebsd.org
To:        freebsd-bugs@FreeBSD.org
Subject:   [Bug 199587] libc strncmp() performance
Message-ID:  <bug-199587-8@https.bugs.freebsd.org/bugzilla/>

next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=199587

            Bug ID: 199587
           Summary: libc strncmp() performance
           Product: Base System
           Version: 10.1-STABLE
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Many People
          Priority: ---
         Component: misc
          Assignee: freebsd-bugs@FreeBSD.org
          Reporter: blackngel1@gmail.com

I've been tinkering with the code, out of curiosity, and I've reimplemented
strncmp() to check the performance. Here are my results and the benchmark code:

         42359800221 cycles -- FreeBSD strncmp()
         42113090043 cycles -- FreeBSD strncmp()
         42145558182 cycles -- FreeBSD strncmp()
         39479522958 cycles -- My Implementation
         39447595998 cycles -- My Implementation
         39445708599 cycles -- My Implementation

My implementation always runs a bit faster and seems more clean.

--------------

#include <stdio.h>

unsigned long long
rdtsc(void)
{
        unsigned int low, hi;
        __asm__ volatile(
            "rdtsc\n"
            : "=a"(low), "=d"(hi)
            :
            : "memory");
        return ((unsigned long long)hi << 32) | (unsigned long long) low;
}

int
strncmpnew(const char *p, const char *q, size_t n)
{
        while (n > 0 && *p && (*p == *q))
                n--, p++, q++;

        return (n == 0) ? 0: ((const unsigned char)*p - (const unsigned
char)*q);
}

int
strncmpfbsd(const char *s1, const char *s2, size_t n)
{

    if (n == 0)
        return (0);
    do {
        if (*s1 != *s2++)
            return (*(const unsigned char *)s1 -
                *(const unsigned char *)(s2 - 1));
        if (*s1++ == '\0')
            break;
    } while (--n != 0);
    return (0);
}

void
test(int (*f)(const char *, const char *, unsigned int n), unsigned int iters,
char *msg)
{
        char *str1 = "abcdefghijklmnopqrstuvwxyz0123456789A";
        char *str2 = "abcdefghijklmnopqrstuvwxyz0123456789A";
        unsigned long foo = 0;

        unsigned long long int st = rdtsc();
        unsigned int i;
        for (i = 0; i < iters; i++)
                foo += f(str1, str2, 37);
        unsigned long long int tot = rdtsc() - st;
        printf("%20llu cycles -- %s\n", tot, msg);
        asm volatile( "" :: "g"(foo) : "memory");
}

int
main(void)
{
        unsigned int iters = 100000000;

        test(strncmpfbsd, iters, "FreeBSD strncmp()");
        test(strncmpfbsd, iters, "FreeBSD strncmp()");
        test(strncmpfbsd, iters, "FreeBSD strncmp()");
        test(strncmpnew, iters, "My Implementation");
        test(strncmpnew, iters, "My Implementation");
        test(strncmpnew, iters, "My Implementation");
        getchar();

        return 0;
}

--------------

-- 
You are receiving this mail because:
You are the assignee for the bug.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-199587-8>