Grep too slow? Use git-grep
developingandstuff.blogspot.de
developingandstuff.blogspot.de
Using a clone of linus' kernel on a six year old amd64 box running debian/sid:
(master):dfc@fob-xray:~/lk$ time git grep "leap second" > /dev/null
real 0m0.739s
user 0m0.540s
sys 0m0.650s
(master):dfc@fob-xray:~/lk$ time grep -r --exclude-dir=.git "leap second" . > /dev/null
real 0m0.833s
user 0m0.400s
sys 0m0.430s
(master):dfc@fob-xray:~/lk$ du -sh .
1.4G .
[1] http://lists.freebsd.org/pipermail/freebsd-current/2010-Augu...ADDENDUM:
After running a test on a Mac mini with 10.8.4 and a clone of the same repository I am overly confident that the title should be "BSD grep too slow? Use git-grep or GNU grep":
jumbo:lk dfc$ purge ; time grep -r --exclude-dir=.git "leap second" . > /dev/null
real 1m8.479s
user 0m32.229s
sys 0m2.348s
jumbo:lk dfc$ purge ; time ggrep -r --exclude-dir=.git "leap second" . > /dev/null
real 0m41.844s
user 0m1.682s
sys 0m6.035s
jumbo:lk dfc$ purge ; time git grep "leap second" > /dev/null
real 0m37.325s
user 0m1.423s
sys 0m4.213s
jumbo:lk dfc$ gdu -sh .
1.3G .
You can read `ggrep` as either GNU grep or good grep.And there's also ack, and ag... no shortage of options that are better than BSD grep, apparently.
It's not "WOW GNU grep is fast!" it's, "wow, BSD grep is slow."
How does it compare to ack? How did you go retraining the muscle memory used to type grep -E?
[1] http://swtch.com/~rsc/regexp/regexp4.html [2] http://code.google.com/p/codesearch/ [3] https://github.com/rliebling/fastrAck
1. http://lists.freebsd.org/pipermail/freebsd-current/2010-Augu...
"Look for specified patterns in the tracked files in the work tree"
http://git-scm.com/docs/git-grep
Presumably, this would exclude a lot of assets or libraries that aren't part of your branch/repo, don't know what the OP's setup was (are those 11K+ files all tracked?).
The limitation, as others have said, is git grep won't match files that are not already checked in.
In a regular directory tree, recursive grep has to open and read directories, stat files, and read (or mmap?) each individual file. The number of system calls is O(N) on the number of directory entries.
I don't know the answer to your question, but the git source is simple and rewards reading.
git grep -w router
But what if you want to match just the word boundary at the start ("rout") or at the end ("outer")? git grep --perl-regexp "\brout"
and for just word endings git grep --perl-regexp "outer\b" $ brew info git
git: stable 1.8.3.2, HEAD
http://git-scm.com
/usr/local/Cellar/git/HEAD (1324 files, 29M) *
Built from source with: --with-blk-sha1 --with-pcre
From: https://github.com/mxcl/homebrew/commits/master/Library/Formula/git.rb
==> Dependencies
Optional: pcre, gettext
==> Options
--with-blk-sha1
Compile with the block-optimized SHA1 implementation
--with-gettext
Build with gettext support
--with-pcre
Build with pcre support
--without-completions
Disable bash/zsh completions from "contrib" directory
What does "built from source with" say? git grep -P "outer\b"
Yay! Thank you and moonboots.This is an important feature for me, because I organize my code lexically (primarily by being disciplined about using unique names for things) and rely on grep to quickly find what I want. Occasionally one unique name overlaps with another, and then I really want to match the word boundary.
So try those. (I don't have a git repo handy to test)
(edit: I tested and it works)
Note, you can also export environment variables for a specific command, if you don't want to change it for your whole shell, by specifying "variable=value" before the command:
LANG=C grep ...ADDENDUM:
I remembered discussing this a while back and I just found my old comment. Someone said "fun fact, gnu grep is slow with UTF8"[1] and I said "funner fact gnu grep was slow with UTF8"[2]. I reran the same grep that I used elsewhere in this discussion with C and with UTF8:
root@fob-xray:lk# sync ; echo 3 > /proc/sys/vm/drop_caches
root@fob-xray:lk# declare -x LANG=C ; /usr/bin/time grep --exclude-dir=.git -r "leap second" . > /dev/null
0.51user 3.04system 1:28.40elapsed 4%CPU (0avgtext+0avgdata 992maxresident)k
0inputs+0outputs (3major+340minor)pagefaults 0swaps
root@fob-xray:lk# sync ; echo 3 > /proc/sys/vm/drop_caches
root@fob-xray:lk# declare -x LANG=en_US.UTF-8 ; /usr/bin/time grep --exclude-dir=.git -r "leap second" . > /dev/null
0.41user 3.44system 1:27.01elapsed 4%CPU (0avgtext+0avgdata 1100maxresident)k
0inputs+0outputs (2major+367minor)pagefaults 0swaps
I think you must have a version of GNU grep before 2.7.3 or 2.7.1. The UTF problem seems to have disappeared. There is a decent amount of information in the debian bug report[3].[1] https://news.ycombinator.com/item?id=2860932
ls -lh |sort +4 -5 -h
doesn't work (at least on my RHEL 6.4 box), yet: ls -lh |LANG=C sort +4 -5 -h
does work. --- /tmp/withutf 2013-07-09 21:03:23.060064079 -0400
+++ /tmp/withC 2013-07-09 21:03:30.069578205 -0400
@@ -1,26 +1,26 @@
total 544K
-rw-r--r-- 1 dfc dfc 252 Jul 9 19:27 Kconfig
-rw-r--r-- 1 dfc dfc 2.5K Jul 9 19:27 Kbuild
-drwxr-xr-x 113 dfc dfc 4.0K Jul 9 19:27 drivers
+drwxr-xr-x 2 dfc dfc 4.0K Jul 9 19:27 init
+drwxr-xr-x 2 dfc dfc 4.0K Jul 9 19:27 ipc
+drwxr-xr-x 2 dfc dfc 4.0K Jul 9 19:27 mm
+drwxr-xr-x 2 dfc dfc 4.0K Jul 9 19:27 usr
+drwxr-xr-x 3 dfc dfc 4.0K Jul 9 19:27 block
+drwxr-xr-x 3 dfc dfc 4.0K Jul 9 19:27 virt
+drwxr-xr-x 4 dfc dfc 4.0K Jul 9 19:27 crypto
+drwxr-xr-x 9 dfc dfc 4.0K Jul 9 19:27 lib
+drwxr-xr-x 9 dfc dfc 4.0K Jul 9 19:27 security
drwxr-xr-x 11 dfc dfc 4.0K Jul 9 19:27 kernel
drwxr-xr-x 12 dfc dfc 4.0K Jul 9 19:27 samples
drwxr-xr-x 13 dfc dfc 4.0K Jul 9 19:27 scripts
drwxr-xr-x 17 dfc dfc 4.0K Jul 9 19:27 tools
drwxr-xr-x 22 dfc dfc 4.0K Jul 9 19:27 sound
drwxr-xr-x 26 dfc dfc 4.0K Jul 9 19:27 include
-drwxr-xr-x 2 dfc dfc 4.0K Jul 9 19:27 init
-drwxr-xr-x 2 dfc dfc 4.0K Jul 9 19:27 ipc
-drwxr-xr-x 2 dfc dfc 4.0K Jul 9 19:27 mm
-drwxr-xr-x 2 dfc dfc 4.0K Jul 9 19:27 usr
drwxr-xr-x 32 dfc dfc 4.0K Jul 9 19:27 arch
drwxr-xr-x 36 dfc dfc 4.0K Jul 9 19:27 firmware
-drwxr-xr-x 3 dfc dfc 4.0K Jul 9 19:27 block
-drwxr-xr-x 3 dfc dfc 4.0K Jul 9 19:27 virt
-drwxr-xr-x 4 dfc dfc 4.0K Jul 9 19:27 crypto
drwxr-xr-x 55 dfc dfc 4.0K Jul 9 19:27 net
drwxr-xr-x 73 dfc dfc 4.0K Jul 9 19:27 fs
-drwxr-xr-x 9 dfc dfc 4.0K Jul 9 19:27 lib
-drwxr-xr-x 9 dfc dfc 4.0K Jul 9 19:27 security
+drwxr-xr-x 113 dfc dfc 4.0K Jul 9 19:27 drivers
-rw-r--r-- 1 dfc dfc 7.4K Jul 9 19:27 REPORTING-BUGS
drwxr-xr-x 101 dfc dfc 12K Jul 9 19:27 Documentation
-rw-r--r-- 1 dfc dfc 19K Jul 9 19:27 COPYING
There were differences in the output but I am not sure if that is a bug or if it has to do with locale rules for sorting. What do you think is broken with sort?There seems to be a bug regarding utf and sort in debian[1] but I am not sure if it is the same problem. Do you know if there is a bug in redhat's bugzilla for the issue? Up until this thread I did not realize sort behaved differently depending on the locale.[2] Are you sure its not a difference in locale expectations on how strings are sorted?
[1] http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=695489
[2] http://stackoverflow.com/questions/5909404/sort-not-sorting-...
It's not git-exclusive and has a ton of additional capabilities and features. Besides, being a pure Python program it's very easy to tweak if there's something you want done differently.
[Disclaimer: shameless plug]