How grep is fast, and when it isn't

grep, sed & awk · Expert · 12 min

Knowing what makes a search slow lets you search gigabytes in seconds instead of minutes.

GNU grep is fast because it avoids doing per-character regex work on most of the input:

  • It extracts a required literal from the pattern (for ERROR [0-9]+ that's ERROR ) and searches for it with a Boyer-Moore-style algorithm that can skip ahead several bytes at a time. Only candidate lines are checked by the full matcher.
  • The full matcher is a DFA built lazily from the regex: each input byte costs one table lookup, with no backtracking, so time is linear in the input size.
  • It reads big blocks and doesn't split the input into lines before matching; it finds line boundaries only around matches.

Things that defeat this:

  • Backreferences like \(a*\)\1 can't be expressed as a DFA, so grep falls back to a backtracking matcher which can be exponential.
  • -P uses PCRE2 (with JIT), fast for typical patterns but backtracking, so pathological patterns can be very slow.
  • Multibyte locales can force slower paths for some constructs; LC_ALL=C often speeds up large ASCII searches.
  • -i with some locales, and patterns with no usable literal, also reduce the skipping.

For many fixed strings use -F -f patterns.txt: grep builds an Aho-Corasick-style matcher that searches for all of them in one pass. Avoid loops that run grep once per pattern over the same file.

Example

# 2 million lines of test data
seq 1 2000000 | sed 's/^/line /' > big.txt

time grep -c 'line 1999999' big.txt        # literal: skips most bytes
time LC_ALL=C grep -c 'line 1999999' big.txt

# many fixed strings in one pass instead of a loop of greps
printf 'line 17\nline 42\nline 99\n' > wanted.txt
grep -cxF -f wanted.txt big.txt            # 3

# backreference: no DFA possible, much slower on big inputs
time grep -cE '(1)\1' big.txt

Remember

  • grep searches for a required literal first, then confirms with a DFA
  • Backreferences and -P fall back to backtracking
  • Use -F -f file for many fixed strings in one pass

Watch out for

  • Looping over a list of terms and running grep once per term on the same large file.

Check yourself

  1. Why are backreferences slow in grep?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: www.gnu.org/software/grep/manual/grep.html#Performance