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:
		
				
					committed by
					
						
						Junio C Hamano
					
				
			
			
				
	
			
			
			
						parent
						
							fb62eb7fab
						
					
				
				
					commit
					c822255cfc
				
			
							
								
								
									
										29
									
								
								grep.c
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								grep.c
									
									
									
									
									
								
							@ -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];
 | 
			
		||||
@ -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;
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user