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