sbase

suckless unix tools
git clone git://git.2f30.org/sbase
Log | Files | Refs | README | LICENSE

commit 4896bdf6de4abc90f2c6a073f065683910d5d15a
parent 5b3a0a9382e41c1129e1fc64ebdd877eb7179952
Author: sin <sin@2f30.org>
Date:   Mon, 12 May 2014 11:59:39 +0100

Revert "Make grep more memory-efficient"

This reverts commit d9a098ae6bc07188cbaefcd188e5911dec41815d.

Conflicts:
	grep.c

Hiltjo Posthuma <hiltjo@codemadness.org> said:

(Re)compiling the regex for each line doesn't make sense (imho) and
slows it down a lot.

A simple test:

time seq 1 100000000 | grep 'a'

sbase grep (before patch):
    0m22.21s real     0m0.00s user     0m0.00s system

sbase grep (after patch):
    2m16.28s real     0m0.00s user     0m0.00s system

coreutils grep:
    0m1.15s real     0m0.00s user     0m0.00s system

So the patch should be reverted I think.

Diffstat:
Mgrep.c | 36++++++++++++++++++------------------
1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/grep.c b/grep.c @@ -11,7 +11,7 @@ enum { Match = 0, NoMatch = 1, Error = 2 }; static void addpattern(const char *); -static bool grep(FILE *, const char *, int); +static bool grep(FILE *, const char *); static bool eflag = false; static bool vflag = false; @@ -20,6 +20,7 @@ static char mode = 0; static struct plist { char *pattern; + regex_t preg; struct plist *next; } *phead; @@ -34,7 +35,7 @@ main(int argc, char *argv[]) { bool match = false; struct plist *pnode, *tmp; - int i, flags = REG_NOSUB; + int i, n, flags = REG_NOSUB; FILE *fp; ARGBEGIN { @@ -61,9 +62,8 @@ main(int argc, char *argv[]) usage(); } ARGEND; - /* no pattern */ if(argc == 0 && !eflag) - usage(); + usage(); /* no pattern */ /* If -e is not specified treat it as if it were */ if(!eflag) { @@ -72,14 +72,23 @@ main(int argc, char *argv[]) argv++; } + /* Compile regex for all search patterns */ + for(pnode = phead; pnode; pnode = pnode->next) { + if((n = regcomp(&pnode->preg, pnode->pattern, flags)) != 0) { + char buf[BUFSIZ]; + + regerror(n, &pnode->preg, buf, sizeof buf); + enprintf(Error, "invalid pattern: %s\n", buf); + } + } many = (argc > 1); if(argc == 0) { - match = grep(stdin, "<stdin>", flags); + match = grep(stdin, "<stdin>"); } else { for(i = 0; i < argc; i++) { if(!(fp = fopen(argv[i], "r"))) enprintf(Error, "fopen %s:", argv[i]); - if(grep(fp, argv[i], flags)) + if(grep(fp, argv[i])) match = true; fclose(fp); } @@ -87,6 +96,7 @@ main(int argc, char *argv[]) pnode = phead; while(pnode) { tmp = pnode->next; + regfree(&pnode->preg); free(pnode->pattern); free(pnode); pnode = tmp; @@ -110,29 +120,20 @@ addpattern(const char *pattern) } bool -grep(FILE *fp, const char *str, int flags) +grep(FILE *fp, const char *str) { - char err[BUFSIZ]; char *buf = NULL; long n, c = 0; - int r; - static regex_t preg; size_t size = 0, len; struct plist *pnode; bool match = false; for(n = 1; afgets(&buf, &size, fp); n++) { for(pnode = phead; pnode; pnode = pnode->next) { - if((r = regcomp(&preg, pnode->pattern, flags)) != 0) { - regerror(r, &preg, err, sizeof err); - enprintf(Error, "invalid pattern: %s\n", err); - } if(buf[(len = strlen(buf))-1] == '\n') buf[--len] = '\0'; - if(regexec(&preg, buf, 0, NULL, 0) ^ vflag){ - regfree(&preg); + if(regexec(&pnode->preg, buf, 0, NULL, 0) ^ vflag) continue; - } switch(mode) { case 'c': c++; @@ -158,7 +159,6 @@ grep(FILE *fp, const char *str, int flags) end: if(ferror(fp)) enprintf(Error, "%s: read error:", str); - regfree(&preg); free(buf); return match; }