Whenever people talk about ack, there’s always a discussion of whether ack is faster than grep, and how much faster, and people provide data points that show “I searched this tree with find+grep in 8.3 seconds, and it took ack 11.5 seconds”. Thing is, that doesn’t take into account the amount of time it takes to type the command.
How much faster is it to type an ack command line vs. a find+xargs line? I wanted to time myself.
Inspired by this tweet by @climagic, I wanted to find out for myself. I used time read to see how long it would take me to type three different command lines.
The three command lines are:
A: ack --perl foo
B: find . -name '*.php' | xargs grep foo
C: find . -name '*.pl' -o -name '*.pm' | xargs grep foo
So I tried it out using time read. Note that it’s not actually executing the command, but measuring how long it takes to hit Enter.
$ time read find . -name '*.pl' -o -name '*.pm' | xargs grep foo real 0m8.648s user 0m0.000s sys 0m0.000s
For me, my timings came out to average about 1.4s for A, 6.1s for B and 8.6s for C. That was with practice. I also found that it is nearly impossible for me to type the punctuation-heavy B and C lines without making typos and having to correct them.
So I ask of you, dear readers, would you please try this little experiment yourself, and then post your results in the comments? Just give me numbers for A, B and C and then also include the name of your favorite Beatle so I know you actually read this. Also, if you have any insights as to why you think your results came out the way they did, please let me know.
At this point I’m just collecting data. It’s imperfect, but I’m OK with that.
- Yes, I’m sure there’s another way I could do this timing. It might even be “better”, for some values of “better”.
- Yes, I know that I’m asking people to report their own data and there may be observational bias.
- Yes, I know I’m excluding Windows users from my sample.
- Yes, I know it’s possible to create shell aliases for long command lines.
- Yes, I know that the find command lines should be using
find -print0andxargs -0. - Yes, I know that some shells have globbing like
**/*.{pl,pm}.
Note: I’ve heard from a zsh user that time doesn’t work for this because it’s a shell function, but /usr/bin/time does work.
Thanks for your help! I’ll report on results in a future post.
April 19, 2012 at 9:21 am
My results:
A: 1.4s
B: 6.1s
C: 8.6s
Paul
April 19, 2012 at 9:26 am
1. 2.588s
2. 10.832s , plus the mistype
3. 17.652s
April 19, 2012 at 9:29 am
A: 1.1s
B: 3.5s
C: 5.6s
I’m too young to answer this question.
April 19, 2012 at 9:35 am
Without practice, first time, without errors:
A: 2.5s
B: 13.9s
C: 19.5
Not George
April 19, 2012 at 9:37 am
A: 1.8s
B: 8.0s
C: 10.2s
And I guess I don’t really have a favorite Beatle.
To be fair, I’m on a keyboard with a strange layout at the moment, so my fingers are still learning how to type ‘|’.
April 19, 2012 at 9:40 am
A: 0m3.599s
B: 0m10.359s
C: 0m14.542s
John
April 19, 2012 at 9:43 am
A: 2.12
B: 6.45
C: 8.85
April 19, 2012 at 9:43 am
A: 1.664
B: 4.823
C: 7.455
John
The thing is, its easy to type the find commands when you’re just copying them. Likewise for the ack command. Another test would be to give someone an example of what you’re trying to do and see how quickly they could come up with the command to solve that problem. If you already know ack, you’ll probably do it quickly, but if you’re new to it, you’ll take time to read the man page. Likewise for find, you may stumble a bit with getting the right syntax for the expressions and then deciding how to use xargs.
ack can be like any other command where once you get used to it your muscle memory starts to kick in. Obviously it has for you as I couldn’t even get close to 1.4sec on multiple tries. Something else that bothers me with ack is that it tries to do a lot and you don’t really have full control over it. For instance, one may have to check what –perl really means and if that means also including .cgi files and perl scripts without extension and if it doesn’t what can I do for it to also check .cgi files in addition to using the –perl flag. Just some things to consider.
April 19, 2012 at 9:52 am
A: 1.9s
B: 10.8s
C: 13.8s
The 5th one.
April 19, 2012 at 9:56 am
everybody is a faster typer than me.
3.1
7.0
11.1
Paul, obviously.
April 19, 2012 at 10:02 am
A: 0m3.002s
B: 0m12.983s
C: 0m18.202s
Paul
I rarely use ‘find’ so the command format is awkward for my fingers to grok.
April 19, 2012 at 10:11 am
A: 2.4
B: 8.2
C: 11.4
The VW Beetle RSI. Or maybe Paul.
April 19, 2012 at 10:16 am
A:2.488
B:7.488
C:10.740 … whoops, had an error. redo: 9.696
George.
April 19, 2012 at 10:25 am
A: 1·6 s
B: 4·9 s
C: 9·5 s
A was slightly longer if I typed “ack-grep” (or “ack-” then pressed Tab), using the name it’s installed by on Debian-based systems.
B was slightly quicker if I omitted the “.” which isn’t needed with Gnu find.
C was quicker if I did that and combined the options into -name ‘*.p[lm]‘.
But in practice I can’t remember the last time I did any of the above. Before I became an ack user I would generally do something like:
$ grep -r foo
— and put up with that also searching some files I didn’t want it to, cos it was faster to ignore any results I wasn’t interested in than to devise and type a more precise command.
Now I mostly just do:
$ ack foo
— which generally doesn’t include extraneous files anyway, since by default it handily ignores log files, editor swap files, version control files, and so on.
If the output from either of the above was too noisy, or they took too long to complete, then my first attempt at restricting them to just Perl files would be along the lines of:
$ grep -r foo lib
or:
$ ack foo lib
So I think the advantage of ack is not that it’s faster to type than the find equivalent command that I never bothered to type anyway; it’s that it gives better output (for slightly less typing).
My favourite Beatles are Bootleg.
April 19, 2012 at 10:32 am
A: 2.459
B: 9.130
C: 11.879 (with typos)
Ringo is the man…
April 19, 2012 at 10:48 am
A: 3.328s
B: 14.717s
C: 20.710s
D: 1.503s my usual use case–”ack foo”
Ringo
And the thing is, sure, you can make shell aliases and stuff to make long commands shorter. But to get as many features as ack has (like coloring and match highlighting), you need to essentially re-invent ack in shell. At that point, it’s easier to just help improve ack than rolling your own solution.
April 19, 2012 at 10:52 am
A:2.672
B:7.631
C:13.112
April 19, 2012 at 11:02 am
A: 2.7
B: 9.6 (ooops, didn’t fix the typo)
C: 18.1 (did fix the typo)
I don’t have a favourite Beatle, but among the members of Queen I prefer Brian.
April 19, 2012 at 11:15 am
A: 0m2.290s
B: 0m10.003s
C: 0m14.863s
I prefer http://www.youtube.com/watch?v=R1rkb8T4WR8
If you insist, I name a favorite song instead: In my life.
April 19, 2012 at 11:34 am
A: 2.736
B: 8.344
C: 11.392 (With an error I didn’t notice until after I hit enter.)
And George, obviously. (We even used What Is Life as the recessional at our wedding.)
April 19, 2012 at 11:47 am
Horrible result
And I don’t really have a favorite Beatle:
A: 3.921
B: 13.728
C: 24.801
April 19, 2012 at 12:12 pm
A: 2.5s
B: 8.0s
C: 11s
Ringo.
April 19, 2012 at 12:25 pm
A: 2.704
B: 6.116
C: 12.315
George
I didn’t have typos on any of them, but I did pause in the middle of C because I lost track of where I was in the string.
April 19, 2012 at 1:14 pm
A:04.15
B:16.06
C:18.19
Nowhere Man (easier to type than “Ob-La-Di Ob-La-Da)
April 19, 2012 at 1:19 pm
A 1.58
B 6.69
C 13.79
I don’t listen to the Beatles.
In practice, I use neither ack nor grep, but the project-wide find in TextMate. (Otherwise I would probably use ack.vim)
April 19, 2012 at 5:07 pm
A 1.618s
B 5.614s
C 8.472s
No particular Beatles preference.
April 20, 2012 at 10:36 am
A: 2.835
B: 10.877
C: 17.680
(Not a programmer, a sysadmin with a Swiss-German keyboard).
No beatle.
April 24, 2012 at 8:51 am
A: 3.736
B: 12.056
C: 19.040
Lucanus cervus
June 7, 2012 at 8:50 am
A: 7.379
B: 22.863
C: 33.44
McCartney
September 12, 2012 at 10:21 am
A: 2.5
B: 6.9
C: 10.7
George
That was after 4 iterations – until I typed it correctly.