Are you sure it behaves *exactly* like the existing one?
I stole the implementation from OpenBSD so it might be a good idea for you 
to send it to them.
They are the best to shed light on this and see if it's exactly the same 
and faster.

Andi

At 09:00 02/05/2002 -0700, Preston L. Bannister wrote:
>Was looking at the strlcat() implementation in the PHP source
>and saw that it does not take advantage of history :).
>
>Look at xxx_strlcat() in the following example.
>
>You are almost always better off using the compiler's built-in
>string functions, due to the optimizations built-in (many years ago)
>to improve Dhrystone benchmark scores.  The benchmark turned out to
>be a bit bogus, but the improvements made to the string functions
>are a benefit to us all :).
>
>This is more readable (and thus more likely correct), slightly faster
>(about 4% in my testing), and in the debug build better checked.
>
>Full comparison benchmark program:
>-----
>#include <stdlib.h>
>#include <stdio.h>
>#include <string.h>
>#include <time.h>
>#include <assert.h>
>
>/*
>  * Appends src to string dst of size siz (unlike strncat, siz is the
>  * full size of dst, not space left).  At most siz-1 characters
>  * will be copied.  Always NUL terminates (unless siz == 0).
>  * Returns strlen(src); if retval >= siz, truncation occurred.
>  */
>size_t php_strlcat(char* dst,const char* src,size_t siz)
>{
>         register char *d = dst;
>         register const char *s = src;
>         register size_t n = siz;
>         size_t dlen;
>
>         /* Find the end of dst and adjust bytes left but don't go past end */
>         while (*d != '\0' && n-- != 0)
>                 d++;
>         dlen = d - dst;
>         n = siz - dlen;
>
>         if (n == 0)
>                 return(dlen + strlen(s));
>         while (*s != '\0') {
>                 if (n != 1) {
>                         *d++ = *s;
>                         n--;
>                 }
>                 s++;
>         }
>         *d = '\0';
>
>         return(dlen + (s - src));       /* count does not include NUL */
>}
>
>/*
>  * Take full advantage of any compiler/library optimizations built in
>  * to the standard string routines.  Look up the history of compiler
>  * comparisons with Dhrystone benchmark to understand why this wins.
>  * Pre-Internet history - check Google's USENET archive.
>  */
>size_t xxx_strlcat(char* s1,const char* s2,size_t nMax)
>{
>     size_t n1 = strlen(s1);
>     size_t n2 = strlen(s2);
>     size_t nCopy = (nMax <= (n1+n2)) ? (nMax - n1 - 1) : n2;
>
>     /* Better to leave this out and require a valid string return */
>     if (!nMax) return 0;
>
>     assert(n1 < nMax);      /* Catch pre-existing oversize strings */
>     assert(0 < nMax);       /* Insure return is always a valid string */
>
>     memcpy(s1+n1,s2,nCopy);
>     s1[n1+nCopy] = 0;
>     return n1+n2;           /* as documented for strlcat() */
>     /*return n1+nCopy;        /* actual number of characters */
>}
>
>/*
>  *
>  */
>int main(int ac, char** av)
>{
>     clock_t t1,dt;
>#ifdef WIN32
>     __int64 nTotal;
>#else
>     long long nTotal;
>#endif
>     char s1[85];
>     static char s2[] = "1234567890";
>     int nLoops = 10;
>
>     if (1 < ac) {
>         nLoops = atoi(av[1]);
>     }
>
>     printf("Compare two strlcat() implementations for %d 
> iterations.\n",nLoops);
>
>     t1 = clock();
>     nTotal = 0;
>     for (int i=0; i<nLoops; ++i) {
>         s1[0] = 0;
>         nTotal += php_strlcat(s1,s2,sizeof(s1));
>         nTotal += php_strlcat(s1,s2,sizeof(s1));
>         nTotal += php_strlcat(s1,s2,sizeof(s1));
>         nTotal += php_strlcat(s1,s2,sizeof(s1));
>         nTotal += php_strlcat(s1,s2,sizeof(s1));
>         nTotal += php_strlcat(s1,s2,sizeof(s1));
>         nTotal += php_strlcat(s1,s2,sizeof(s1));
>         nTotal += php_strlcat(s1,s2,sizeof(s1));
>         nTotal += php_strlcat(s1,s2,sizeof(s1));
>         nTotal += php_strlcat(s1,s2,sizeof(s1));
>     }
>     dt = clock() - t1;
>
>     printf("php_strlcat() copied %1.0f characters in %ld 
> ticks\n",(double)nTotal,(long)dt);
>
>     t1 = clock();
>     nTotal = 0;
>     for (i=0; i<nLoops; ++i) {
>         s1[0] = 0;
>         nTotal += xxx_strlcat(s1,s2,sizeof(s1));
>         nTotal += xxx_strlcat(s1,s2,sizeof(s1));
>         nTotal += xxx_strlcat(s1,s2,sizeof(s1));
>         nTotal += xxx_strlcat(s1,s2,sizeof(s1));
>         nTotal += xxx_strlcat(s1,s2,sizeof(s1));
>         nTotal += xxx_strlcat(s1,s2,sizeof(s1));
>         nTotal += xxx_strlcat(s1,s2,sizeof(s1));
>         nTotal += xxx_strlcat(s1,s2,sizeof(s1));
>         nTotal += xxx_strlcat(s1,s2,sizeof(s1));
>         nTotal += xxx_strlcat(s1,s2,sizeof(s1));
>     }
>     dt = clock() - t1;
>
>     printf("xxx_strlcat() copied %1.0f characters in %ld 
> ticks\n",(double)nTotal,(long)dt);
>
>     return 0;
>}
>-----
>
>--
>Preston L. Bannister
>http://members.cox.net/preston.bannister/
>pbannister on Yahoo Messenger
>
>--
>PHP Development Mailing List <http://www.php.net/>
>To unsubscribe, visit: http://www.php.net/unsub.php


-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to