git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 1/2] grep -w: forward to next possible position after rejected match

From
René Scharfe <rene.scharfe@lsrfire.ath.cx>
Date
Jan 9, 2009, 23:08 UTC
Message-ID
<4967D8F8.9070508@lsrfire.ath.cx>

grep -w accepts matches between non-word characters, only. If a match from regexec() doesn't meet this criteria, grep continues its search after the first character of that match.

We can be a bit smarter here and skip all positions that follow a word character first, as they can't match our criteria. This way we can consume characters quite cheaply and don't need to special-case the handling of the beginning of a line.

Here's a contrived example command on msysgit (best of five runs):
	$ time git grep -w ...... v1.6.1 >/dev/null
	real    0m1.611s
	user    0m0.000s
	sys     0m0.015s
With the patch it's quite a bit faster:
	$ time git grep -w ...... v1.6.1 >/dev/null
	real    0m1.179s
	user    0m0.000s
	sys     0m0.015s

More common search patterns will gain a lot less, but it's a nice clean up anyway.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
 grep.c |   11 +++++++----
 1 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/grep.c b/grep.c
index 49e9319..394703b 100644
--- a/grep.c
+++ b/grep.c
@@ -294,7 +294,6 @@ static struct {
 static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol, char *eol, enum grep_context ctx)
 {
 	int hit = 0;
-	int at_true_bol = 1;
 	int saved_ch = 0;
 	regmatch_t pmatch[10];
 
@@ -337,7 +336,7 @@ static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol
 		 * either end of the line, or at word boundary
 		 * (i.e. the next char must not be a word char).
 		 */
-		if ( ((pmatch[0].rm_so == 0 && at_true_bol) ||
+		if ( ((pmatch[0].rm_so == 0) ||
 		      !word_char(bol[pmatch[0].rm_so-1])) &&
 		     ((pmatch[0].rm_eo == (eol-bol)) ||
 		      !word_char(bol[pmatch[0].rm_eo])) )
@@ -349,10 +348,14 @@ static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol
 			/* There could be more than one match on the
 			 * line, and the first match might not be
 			 * strict word match.  But later ones could be!
+			 * Forward to the next possible start, i.e. the
+			 * next position following a non-word char.
 			 */
 			bol = pmatch[0].rm_so + bol + 1;
-			at_true_bol = 0;
-			goto again;
+			while (word_char(bol[-1]) && bol < eol)
+				bol++;
+			if (bol < eol)
+				goto again;
 		}
 	}
 	if (p->token == GREP_PATTERN_HEAD && saved_ch)
-- 
1.6.1
Next: René Scharfe
Message 1 of 12 in “grep -w: forward to next possible position after rejected match”
  1. 1/2 grep -w: forward to next possible position after rejected matchRené Scharfe, Jan 9, 2009
  2. 2/2 grep: don't call regexec() for fixed stringsRené Scharfe, Jan 9, 2009
  3. Junio C HamanoJan 10, 2009
  4. Mikael MagnussonJan 12, 2009
  5. Johannes SchindelinJan 12, 2009
  6. Alex RiesenJan 12, 2009
  7. René ScharfeJan 12, 2009
  8. Junio C HamanoJan 13, 2009
  9. 1/4 Add ctype testRené Scharfe, Jan 17, 2009
  10. 2/4 Reformat ctype.cRené Scharfe, Jan 17, 2009
  11. 3/4 Change NUL char handling of isspecial()René Scharfe, Jan 17, 2009
  12. 4/4 Add is_regex_special()René Scharfe, Jan 17, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.