By now the Useless Use of cat
Award is very well known, and there's also a mention of a Useless Use of echo
(not relevant for this question). I'm wondering if there should be a "Useless Use of echo
in Bash Award": Piping seems to be much slower than heredocs and herestrings according to some highly unscientific measurements:
-
Heredocs:
for reps in 1 2 3 do time for i in {1..1000} do cat <<'END' test string END done > /dev/null done real 0m1.786s user 0m0.212s sys 0m0.332s real 0m1.817s user 0m0.232s sys 0m0.332s real 0m1.846s user 0m0.256s sys 0m0.320s
-
Herestrings
for reps in 1 2 3 do time for i in {1..1000} do cat <<< 'test string' done > /dev/null done real 0m1.932s user 0m0.280s sys 0m0.288s real 0m1.956s user 0m0.248s sys 0m0.348s real 0m1.968s user 0m0.268s sys 0m0.324s
-
Redirection
for reps in 1 2 3 do time for i in {1..1000} do echo 'test string' | cat done > /dev/null done real 0m3.562s user 0m0.416s sys 0m0.548s real 0m3.924s user 0m0.384s sys 0m0.604s real 0m3.343s user 0m0.400s sys 0m0.552s
In general, heredocs and herestrings are about the same speed (this is just one data set from several tests) while redirection is consistently more than 50% slower. Am I misunderstanding something, or could this be used as a general rule for commands reading standard input in Bash?
Best Answer
First, let's concentrate on performance. I ran benchmarks for a slightly different program on an otherwise mostly idle x86_64 processor running Debian squeeze.
herestring.bash
, using a herestring to pass a line of input:heredoc.bash
, using a heredoc to pass a line of input:echo.bash
, usingecho
and a pipe to pass a line of input:For comparison, I also timed the scripts under ATT ksh93 and under dash (except for
herestring.bash
, because dash doesn't have herestrings).Here are median-of-three times:
Conclusions:
echo
and a pipe is noticeably, but not dramatically faster. (Keep in mind that this is a toy program: in a real program, most of the processing time would be in whatever thetr
call stands for here.)Beyond performance, there's also clarity and portability.
<<<
is a ksh93/bash/zsh extension which is less well-known thanecho … |
or<<
. It doesn't work in ksh88/pdksh or in POSIX sh.The only place where
<<<
is arguably significantly clearer is inside a heredoc:vs
(Most shells can't cope with closing the parenthesis at the end of the line containing
<<EOF
.)