@matheusbsbs / matheus-bagliano / commits / c822255cfc
Fork 0

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>

René Scharfe committed Jan 10, 2009 at 00:18 UTC c822255cfc1ac83daeeeee1647e3c775450c830c
2 files changed +26 -4
grep.c
+25 -4
@@ -28,9 +28,31 @@ void append_grep_pattern(struct grep_opt *opt, const char *pat,
28 p->next = NULL;
29 }
30
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 +
44 static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)
45 {
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);
56 if (err) {
57 char errbuf[1024];
58 char where[1024];
@@ -159,8 +181,7 @@ void compile_grep_patterns(struct grep_opt *opt)
181 case GREP_PATTERN: /* atom */
182 case GREP_PATTERN_HEAD:
183 case GREP_PATTERN_BODY:
162 - if (!opt->fixed)
163 - compile_regexp(p, opt);
184 + compile_regexp(p, opt);
185 break;
186 default:
187 opt->extended = 1;
@@ -314,7 +335,7 @@ static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol
335 }
336
337 again:
317 - if (!opt->fixed) {
338 + if (!p->fixed) {
339 regex_t *exp = &p->regexp;
340 hit = !regexec(exp, bol, ARRAY_SIZE(pmatch),
341 pmatch, 0);
grep.h
+1
@@ -30,6 +30,7 @@ struct grep_pat {
30 const char *pattern;
31 enum grep_header_field field;
32 regex_t regexp;
33 + unsigned fixed:1;
34 };
35
36 enum grep_expr_node {