Page MenuHomeFreeBSD

Fix for grep -i slowness (patch to libregex)
Needs ReviewPublic

Authored by titus_edc.ro on Nov 28 2025, 3:43 PM.
Tags
None
Referenced Files
F163082508: D53978.diff
Sun, Jul 19, 10:20 PM
Unknown Object (File)
Wed, Jul 15, 4:35 PM
Unknown Object (File)
Wed, Jul 15, 3:50 PM
Unknown Object (File)
Sat, Jul 4, 3:40 AM
Unknown Object (File)
Fri, Jul 3, 11:03 AM
Unknown Object (File)
Fri, Jul 3, 7:12 AM
Unknown Object (File)
May 26 2026, 3:46 AM
Unknown Object (File)
May 21 2026, 8:32 AM

Details

Reviewers
cracauer
Group Reviewers
Src Committers
Summary

grep -i is extremely slow for moderate and longer patterns
the reason is the current code expands any case insensitive string like "findme" to [Ff][iI][nN][dD][Mm][eE]
this prevents the creation of a "must" pattern on which to run Boyer-Moore

the patch tries to fix it

[titus@utmbox ~/builds]$ find /usr/src/sys/ -name \*.c -type f|xargs cat >/tmp/bigfile.txt
[titus@utmbox ~/builds]$ time grep -c FreeBSD /tmp/bigfile.txt
4044

real 0m0.243s
user 0m0.227s
sys 0m0.016s
[titus@utmbox ~/builds]$ time grep -ic FreeBSD /tmp/bigfile.txt
7835

real 0m8.652s
user 0m8.621s
sys 0m0.032s

#so the case insensitive run si 30-40 times slower. its worse for longer patterns

#load patched library
[titus@utmbox ~/builds]$ export LD_LIBRARY_PATH=/usr/obj/home/titus/builds/usr/src/arm64.aarch64/lib/libregex/
[titus@utmbox ~/builds]$ time grep -ic FreeBSD /tmp/bigfile.txt
7835

real 0m0.263s
user 0m0.231s
sys 0m0.032s

Test Plan

i ran NetBSDs libregex test suite against it and it passes

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

Titus, are you still around? I want to put some steam behind this.

A benchmark that is easy to reproduce for everybody:

cd /usr/src/sys && find . -name \*.[ch] | ctime xargs grep -i -n preempt_thresh

no -i old code:
0:00.61 0.61 real 0.48 user 0.10 sys 95% CPU 0/1114 faults
old code -i:
0:24.59 24.59 real 24.44 user 0.11 sys 99% CPU 0/1047 faults
patch -i:
0:00.65 0.65 real 0.53 user 0.09 sys 95% CPU 0/1091 faults
patch no -i:
0:00.64 0.64 real 0.55 user 0.05 sys 95% CPU 0/1081 faults

A benchmark that is easy to reproduce for everybody:

cd /usr/src/sys && find . -name \*.[ch] | ctime xargs grep -i -n preempt_thresh

no -i old code:
0:00.61 0.61 real 0.48 user 0.10 sys 95% CPU 0/1114 faults
old code -i:
0:24.59 24.59 real 24.44 user 0.11 sys 99% CPU 0/1047 faults
patch -i:
0:00.65 0.65 real 0.53 user 0.09 sys 95% CPU 0/1091 faults
patch no -i:
0:00.64 0.64 real 0.55 user 0.05 sys 95% CPU 0/1081 faults

Confirmed.

usr/src/lib/libc/regex/engine.c
151

Not sure why we've added two blank lines here.

1130

Why two blank lines?