Skip to content

Commit

Permalink
grep: don't call regexec() for fixed strings
Browse files Browse the repository at this point in the history
Add the new flag "fixed" to struct grep_pat and set it if the pattern
is doesn't contain any regex control characters in addition to if the
flag -F/--fixed-strings was specified.

This gives a nice speed up on msysgit, where regexec() seems to be
extra slow.  Before (best of five runs):

	$ time git grep grep v1.6.1 >/dev/null

	real    0m0.552s
	user    0m0.000s
	sys     0m0.000s

	$ time git grep -F grep v1.6.1 >/dev/null

	real    0m0.170s
	user    0m0.000s
	sys     0m0.015s

With the patch:

	$ time git grep grep v1.6.1 >/dev/null

	real    0m0.173s
	user    0m0.000s
	sys     0m0.000s

The difference is much smaller on Linux, but still measurable.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
René Scharfe authored and Junio C Hamano committed Jan 10, 2009
1 parent fb62eb7 commit c822255
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 4 deletions.
29 changes: 25 additions & 4 deletions grep.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,31 @@ void append_grep_pattern(struct grep_opt *opt, const char *pat,
p->next = NULL;
}

static int isregexspecial(int c)
{
return isspecial(c) || c == '$' || c == '(' || c == ')' || c == '+' ||
c == '.' || c == '^' || c == '{' || c == '|';
}

static int is_fixed(const char *s)
{
while (!isregexspecial(*s))
s++;
return !*s;
}

static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)
{
int err = regcomp(&p->regexp, p->pattern, opt->regflags);
int err;

if (opt->fixed || is_fixed(p->pattern))
p->fixed = 1;
if (opt->regflags & REG_ICASE)
p->fixed = 0;
if (p->fixed)
return;

err = regcomp(&p->regexp, p->pattern, opt->regflags);
if (err) {
char errbuf[1024];
char where[1024];
Expand Down Expand Up @@ -159,8 +181,7 @@ void compile_grep_patterns(struct grep_opt *opt)
case GREP_PATTERN: /* atom */
case GREP_PATTERN_HEAD:
case GREP_PATTERN_BODY:
if (!opt->fixed)
compile_regexp(p, opt);
compile_regexp(p, opt);
break;
default:
opt->extended = 1;
Expand Down Expand Up @@ -314,7 +335,7 @@ static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol
}

again:
if (!opt->fixed) {
if (!p->fixed) {
regex_t *exp = &p->regexp;
hit = !regexec(exp, bol, ARRAY_SIZE(pmatch),
pmatch, 0);
Expand Down
1 change: 1 addition & 0 deletions grep.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ struct grep_pat {
const char *pattern;
enum grep_header_field field;
regex_t regexp;
unsigned fixed:1;
};

enum grep_expr_node {
Expand Down

0 comments on commit c822255

Please sign in to comment.