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