зеркало из https://github.com/microsoft/git.git
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:
Родитель
fb62eb7fab
Коммит
c822255cfc
27
grep.c
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
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 {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче