Date: Wed, 10 Oct 2001 15:29:00 +0400 (MSD) From: "Andrew L. Neporada" <andrew@nas.dgap.mipt.ru> To: Mike Barcroft <mike@FreeBSD.ORG> Cc: audit@FreeBSD.ORG, freebsd-hackers@FreeBSD.ORG Subject: Re: strnstr(3) - New libc function for review Message-ID: <Pine.BSF.4.21.0110101522160.50053-200000@nas.dgap.mipt.ru> In-Reply-To: <20011004215706.B34530@coffee.q9media.com>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --] I think you should write in ststr.3 that strnstr locates first occurrence of null-terminated string 'little' in ___null-terminated___ string 'big'. Andrew. P.S. Because str(n)str functions deal with null-terminated strings (i.e. we don't know sizes of strings), it is impossible to write algorithm, that will work faster (in average) than current implementation. P.P.S. In the case of binary strings it is possible to implement faster search -- see attachment. On Thu, 4 Oct 2001, Mike Barcroft wrote: > [BCC'd to -hackers for additional comments.] > > Hello, > I would appreciate comments/reviews of the following new addition to > libc. It is largely based off the current strstr(3) implementation. > > Patch attached and also available at: > http://people.FreeBSD.org/~mike/patches/strnstr.diff > > > Best regards, > Mike Barcroft > [-- Attachment #2 --] #include <sys/types.h> #include <sys/time.h> #include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define STRSZ (100*1024) #define PATSZ 500 #define TRYS 100 void * bstrstr(s, slen, p, plen) register const void *s, *p; size_t slen, plen; { register const u_char *str, *substr; register size_t i, max_shift, curr_shift; size_t shift[UCHAR_MAX + 1]; if (s == NULL || p == NULL || plen > slen || slen == 0 || plen == 0) return (NULL); str = (const u_char *)s; substr = (const u_char *)p; for (i = 0; i <= UCHAR_MAX; i++) shift[i] = plen + 1; for (i = 0; i < plen; i++) shift[substr[i]] = plen - i; i = 0; max_shift = slen - plen; while (i <= max_shift) { if (*str == *substr && !memcmp(str + 1, substr + 1, plen -1)) return ((void *)str); curr_shift = shift[str[plen]]; str += curr_shift; i += curr_shift; } return (NULL); } int main(void) { char *str; struct timeval before, after; size_t i; srandomdev(); str = (char *)malloc(STRSZ + PATSZ + 1); if (!str) { printf("no mem\n"); exit(1); } for (i = 0; i < STRSZ + PATSZ; i++) { str[i] = random() & 0xff; if (!str[i]) str[i] = 1; } str[STRSZ + PATSZ] = 0; printf("slen = %d, plen = %d\n", STRSZ + PATSZ, PATSZ); gettimeofday(&before, NULL); for (i = 0; i < TRYS; i++) strstr(str, str + STRSZ); gettimeofday(&after, NULL); after.tv_sec -= before.tv_sec; after.tv_usec -= before.tv_usec; printf("Old: %f sec\n", (after.tv_sec + after.tv_usec/1000000.0)/TRYS); gettimeofday(&before, NULL); for (i = 0; i < TRYS; i++) bstrstr(str, STRSZ + PATSZ, str + STRSZ, PATSZ); gettimeofday(&after, NULL); after.tv_sec -= before.tv_sec; after.tv_usec -= before.tv_usec; printf("New: %f sec\n", (after.tv_sec + after.tv_usec/1000000.0)/TRYS); free(str); return (0); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.21.0110101522160.50053-200000>
