Skip to content

Commit c822255

Browse files
René Scharfegitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent fb62eb7 commit c822255

File tree

2 files changed

+26
-4
lines changed

2 files changed

+26
-4
lines changed

grep.c

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,31 @@ void append_grep_pattern(struct grep_opt *opt, const char *pat,
2828
p->next = NULL;
2929
}
3030

31+
static int isregexspecial(int c)
32+
{
33+
return isspecial(c) || c == '$' || c == '(' || c == ')' || c == '+' ||
34+
c == '.' || c == '^' || c == '{' || c == '|';
35+
}
36+
37+
static int is_fixed(const char *s)
38+
{
39+
while (!isregexspecial(*s))
40+
s++;
41+
return !*s;
42+
}
43+
3144
static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)
3245
{
33-
int err = regcomp(&p->regexp, p->pattern, opt->regflags);
46+
int err;
47+
48+
if (opt->fixed || is_fixed(p->pattern))
49+
p->fixed = 1;
50+
if (opt->regflags & REG_ICASE)
51+
p->fixed = 0;
52+
if (p->fixed)
53+
return;
54+
55+
err = regcomp(&p->regexp, p->pattern, opt->regflags);
3456
if (err) {
3557
char errbuf[1024];
3658
char where[1024];
@@ -159,8 +181,7 @@ void compile_grep_patterns(struct grep_opt *opt)
159181
case GREP_PATTERN: /* atom */
160182
case GREP_PATTERN_HEAD:
161183
case GREP_PATTERN_BODY:
162-
if (!opt->fixed)
163-
compile_regexp(p, opt);
184+
compile_regexp(p, opt);
164185
break;
165186
default:
166187
opt->extended = 1;
@@ -314,7 +335,7 @@ static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol
314335
}
315336

316337
again:
317-
if (!opt->fixed) {
338+
if (!p->fixed) {
318339
regex_t *exp = &p->regexp;
319340
hit = !regexec(exp, bol, ARRAY_SIZE(pmatch),
320341
pmatch, 0);

grep.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ struct grep_pat {
3030
const char *pattern;
3131
enum grep_header_field field;
3232
regex_t regexp;
33+
unsigned fixed:1;
3334
};
3435

3536
enum grep_expr_node {

0 commit comments

Comments
 (0)