grep: don't call regexec() for fixed strings

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>
This commit is contained in:
René Scharfe 2009-01-10 00:18:34 +01:00 коммит произвёл Junio C Hamano
Родитель fb62eb7fab
Коммит c822255cfc
2 изменённых файлов: 26 добавлений и 4 удалений

27
grep.c
Просмотреть файл

@ -28,9 +28,31 @@ void append_grep_pattern(struct grep_opt *opt, const char *pat,
p->next = NULL; 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) 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) { if (err) {
char errbuf[1024]; char errbuf[1024];
char where[1024]; char where[1024];
@ -159,7 +181,6 @@ void compile_grep_patterns(struct grep_opt *opt)
case GREP_PATTERN: /* atom */ case GREP_PATTERN: /* atom */
case GREP_PATTERN_HEAD: case GREP_PATTERN_HEAD:
case GREP_PATTERN_BODY: case GREP_PATTERN_BODY:
if (!opt->fixed)
compile_regexp(p, opt); compile_regexp(p, opt);
break; break;
default: default:
@ -314,7 +335,7 @@ static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol
} }
again: again:
if (!opt->fixed) { if (!p->fixed) {
regex_t *exp = &p->regexp; regex_t *exp = &p->regexp;
hit = !regexec(exp, bol, ARRAY_SIZE(pmatch), hit = !regexec(exp, bol, ARRAY_SIZE(pmatch),
pmatch, 0); pmatch, 0);

1
grep.h
Просмотреть файл

@ -30,6 +30,7 @@ struct grep_pat {
const char *pattern; const char *pattern;
enum grep_header_field field; enum grep_header_field field;
regex_t regexp; regex_t regexp;
unsigned fixed:1;
}; };
enum grep_expr_node { enum grep_expr_node {