Sift: Grep on steroids
sift-tool.org
sift-tool.org
I've read a bit about ag, which is rather fast compared to anything in the wild, and it seems that it utilises all tools to make it as fast as possible. Though, sift can be up to 8 times as fast. How?
EDIT: also I remember, that the last time it was posted here (or either /r/programming), the benchmark was considered not true. Few checks on few folders (from big to small) renders sift slower than ag from 5 to 20 times (though probably faster than grep and/or ack).
EDIT2: https://github.com/svent/sift/issues/7 - about benchmarks. Maybe numbers are true, but they are done in rather specific conditions, with specific cases, where sift can be possibly faster. But in general development it will be rather slow.
$ export LC_ALL=C; grep ...
The regular grep works on Unicode, which can be 10 times slow. Sift works on plain bytes. Also sift benchmark is somewhat inflated. Test on your own data.Sift is a neat tool and I hope people get a lot of use out of it. That said, I don't think the chosen benchmarks are indicative of real-world performance. For example, I just downloaded the latest Linux kernel source, built it, and ran sift and ag on it. This is on a Core i7 4770K with 32GB of RAM and an Intel 330 series SSD. Times are medians of 5 runs each. FS cache was hot.
ggreer@lithium:~/Downloads/linux-4.3% du -sh
12G .
ggreer@lithium:~/Downloads/linux-4.3% time ~/code/sift/sift -n --group line_number
...
~/code/sift/sift -n --group line_number 10.03s user 1.59s system 625% cpu 1.856 total
ggreer@lithium:~/Downloads/linux-4.3% time ag line_number
...
ag line_number 0.68s user 1.03s system 459% cpu 0.371 total
0.37s vs 1.86s. You can see the output of both commands in my gist[1]. Ag obeys .gitignore/hgignore/etc by default, so it shows fewer results.[2] Since sift can't search files with greater than 2^18 characters between newlines, it prints out quite a few error messages. This typically happens with binary files and minified css/js.You may be wondering why I added command line options to sift. They are to enable grouping and line numbers, making the output similar to ag. This may seem cosmetic, but it actually affects performance. Displaying line numbers means you have to count line numbers. That requires reading the entire matching file and adding up the newlines.
One last bit of benchmarking: If I tell ag to do an unrestricted search (meaning both ag and sift search the same files) and I tell sift to format its output like ag (meaning both count line numbers), the results are much closer. Sift takes 1.85 seconds. Ag takes 1.60 seconds. But unlike sift, ag doesn't bail on big files without newlines. It dutifully reports all the matching .o files.
Really though, sift and ag are trying to solve different problems. I designed ag to be a code searching tool. From what I can tell, sift is meant to be more of a grep replacement. Instead of worrying so much about which one is faster, use the right tool for the job.
1. https://gist.github.com/ggreer/96ed22bab57d1e791b9d
2. I consider this a feature. The goal of ag is to find what you're looking for, not to show everything remotely related to what you're looking for. If the default search doesn't find anything, you can quickly add the "-a" option.
https://github.com/ggreer/the_silver_searcher/wiki/Advanced-...
To "ignore" super-long lines, we can just use a Unix filter:
ag --color --group <pattern> | cut -c -100
the --color and --group force ag to not change the output just because we're piping the output to something that isn't a tty. The cut command simply clamps all lines at 100 chars; feel free to change this length.This is pretty long, so we could write a wrapper function or something:
agc() {
ag --color --group $@ | cut -c -100
}
Stick it in your zshrc and you're good to go.This is true, and it's too bad that the optimistic benchmarks featured in the sift web page invite the discussion to center around performance, which is not sift's particular strength.
As for the additional features, I am not looking forward to memorizing more command line crap. Anyone want to write an Emacs/helm package?
alias s=sift
alias a=ag
Now they are even.The other two affordances that caught my attention on that page are (optional) multiline captures, e.g. for XML entities that might span lines, and the --replace modifier, which can transform a captured bit of text, simplifying the
grep var= FILE | sed 's/var=\(.*\);/\1/'
usage pattern.>This takes about 1 second - sift processed 40 million records / 1 GB of data in just one second.
Ex. i have a dir with 2 million files with an avg size of about 3 kilobytes.
ls -f /data/ | wc -l
2183060
So I try to find a pattern: time find "/data/" -name "*txt" -type f -print0 | LC_ALL=C xargs -0 -P 6 -n 40 fgrep -iq "let the right one in"
real 0m3.755s
user 0m3.085s
sys 0m17.764s
Then try sift with same command: time find "/data/" -name "*txt" -type f -print0 | LC_ALL=C xargs -0 -P 6 -n 40 sift -iq "let the right one in
real 0m35.956s
user 0m55.170s
sys 3m32.120s
Or try sift by itself: time sift -rq --files="*txt" "let the right one in" /data/
And it is: real 0m9.298s
user 0m29.620s
sys 0m12.371s
Sticking with grep for now.time sift -z ',R,' 20151104-00.gz | wc -l 210740
real 0m43.725s user 1m9.984s sys 0m10.695s
time zgrep ',R,' 20151104-00.gz | wc -l 210740
real 0m7.262s user 0m7.509s sys 0m1.395s
Great for looking through Android code, when you want to find API call X used along with API call Y.
> No installation. just download a single file.
Is it really so hard for people to provide .rpm/.deb these days? Are man pages extinct as well?
While I support that being an option, providing packaging is really preferable from a deployment and basic system cleanliness standpoint. Software lifecycle management requires packaging of some form (with the most extreme form being entire images, ala docker, et al., of course).
Having a simple build process is more helpful to packagers than something already built since distros are just going to repackage it anyway. Also, few developers are intimately familiar with their OS's packaging standards so they're just asking for obscure incompatibilities.
Man pages though -- for the love of god we need to keep them alive. No they're not fun to write but they're perhaps the most useful tool in the Linux ecosystem. I write them for all of my projects but I assume I'm in the minority at this point.
More and more documentation is being pushed to the web and/or the offline version is just a dump of the website. It's not bad but everyone has a different interpretation of what good documentation looks like and it requires a relatively modern web browser to view, users have to relearn how it's organized, and projects take the mentality that complete documentation isn't something that should be part of a release rather than the thing that's updated every now and then.
Gnu's `info' was supposed to be the replacement. But I seldom look at their documentation.
Also you're correct about about the packaging. It's not particularly difficult to do basic packaging, but the official maintainers for projects like Debian are very particular (rightly so) and would likely end up redoing the packaging from scratch before accepting it.
Not a Unix tool, I see.