Live data from Hacker News

Benchmarking shell pipelines and the Unix “tools” philosophy

blog.plover.com

41–50 of 66 posts

Re: Benchmarking shell pipelines and the Unix “tools” philosophy

#41
the ACTUAL benchmark should be:

1) start timer

2) start deciding which commands to pipeline together

3) run the commands

4) stop timer

a lot of times the decision is the long pole.

in this authors case it included:

5) try a couple more variants of steps 2 and 3

6) write a blog post

:)

Re: Benchmarking shell pipelines and the Unix “tools” philosophy

#42
post #31

for i in $(seq 1 20); do (run once and emit the total CPU time) done |addup "Here we don't actually care about the output (we never actually use $i) but it's a convenient way to get the for loop to run twenty times." This is slower than not running seq and just using builtins. n=1;while true;do test $n -le 20||break; (run once and emit the total CPU time) n=$((n+1)); done |addup

The author did say convenient , not fast. If you don't want the inefficiencies of seq, bash has: for (( expr1 ; expr2 ; expr3 )) ; do list ; done which is a lot more idiomatic than constructing a for loop out of a while loop.

[deleted]

Re: Benchmarking shell pipelines and the Unix “tools” philosophy

#43
post #32

Earlier quoted context omitted.

/bin/bash won't usually ship with a BSDish OS because of the license, so it is not generally portable to use bash-isms. (HPUX, IRIX, SunOS, Solaris, etc. I don't reckon would have had bash either)

Not to mention once installed on a BSD it would most likely reside in /usr/bin/bash (OpenBSD for instance)

Or /usr/local/bin/bash (on FreeBSD).

Re: Benchmarking shell pipelines and the Unix “tools” philosophy

#44
post #26

Earlier quoted context omitted.

Thanks for explaining my own comment to me.

Not explaining, trying to tell that you are comparing apples to oranges and making a conclusion based on that. Also, you don't need to spawn a subshell nor feed sort via stdin in the first example :)

He's comparing apples to oranges and reaching the conclusion that... yes, apples and oranges are different things. He's quite aware of this, and even points out the tradeoff -- `sort | uniq -c` still works if your dataset doesn't fit into RAM.

Re: Benchmarking shell pipelines and the Unix “tools” philosophy

#45
post #31

for i in $(seq 1 20); do (run once and emit the total CPU time) done |addup "Here we don't actually care about the output (we never actually use $i) but it's a convenient way to get the for loop to run twenty times." This is slower than not running seq and just using builtins. n=1;while true;do test $n -le 20||break; (run once and emit the total CPU time) n=$((n+1)); done |addup

The author refers to "the shell" in his "benchmark" but if he is a Linux user then

   sh -c 'f 11 access.2020-01-* ... is dash
whereas

   f 11 access.2020-01* ... is bash
Needless to say, one of these shells is much faster than the other and only one contains the "time" builtin command.

https://wiki.ubuntu.com/DashAsBinSh

Then there is the use of perl and its system command in "count". As with seq, why is perl needed. No explanation. Why not just put the entire pipeline into a perl system command.

Re: Benchmarking shell pipelines and the Unix “tools” philosophy

#46
post #41

the ACTUAL benchmark should be: 1) start timer 2) start deciding which commands to pipeline together 3) run the commands 4) stop timer a lot of times the decision is the long pole. in this authors case it included: 5) try a couple more variants of steps 2 and 3 6) write a blog post :)

This is a good point about the second half of the article (compositonality), but the author started the article by saying this was a command he "sometimes runs", presumably indicating he has it saved somewhere.

Re: Benchmarking shell pipelines and the Unix “tools” philosophy

#47
post #4

Thanks for this! Another nice thing about /usr/bin/time is the --verbose flag which gives: Command being timed: "ls" User time (seconds): 0.00 System time (seconds): 0.00 Percent of CPU this job got: 0% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00 Average shared text size (kbytes): 0 Average unshared data size (kbytes): 0 Average stack size (kbytes): 0 Average total size (kbytes): 0 Maximum resident set size…

Can anyone comment why you can only use the verbose flag if you use the full path of time?

    time -v ls
does not work but

    /usr/bin/time -v ls
does? I don't have enough knowledge of either linux applications or bash to know whats happening to cause this.

Re: Benchmarking shell pipelines and the Unix “tools” philosophy

#48
post #47
post #4

Thanks for this! Another nice thing about /usr/bin/time is the --verbose flag which gives: Command being timed: "ls" User time (seconds): 0.00 System time (seconds): 0.00 Percent of CPU this job got: 0% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00 Average shared text size (kbytes): 0 Average unshared data size (kbytes): 0 Average stack size (kbytes): 0 Average total size (kbytes): 0 Maximum resident set size…

Can anyone comment why you can only use the verbose flag if you use the full path of time? time -v ls does not work but /usr/bin/time -v ls does? I don't have enough knowledge of either linux applications or bash to know whats happening to cause this.

Your shell has a built-in "time" command.

man bash:

    If the time reserved word precedes a pipeline, the elapsed as well
    as user and system time consumed by its execution are reported when
    the pipeline terminates.
man time:

     Some shells may provide a builtin time command which is similar
     or identical to this utility.  Consult the builtin(1) manual page.

Re: Benchmarking shell pipelines and the Unix “tools” philosophy

#49
post #47
post #4

Thanks for this! Another nice thing about /usr/bin/time is the --verbose flag which gives: Command being timed: "ls" User time (seconds): 0.00 System time (seconds): 0.00 Percent of CPU this job got: 0% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00 Average shared text size (kbytes): 0 Average unshared data size (kbytes): 0 Average stack size (kbytes): 0 Average total size (kbytes): 0 Maximum resident set size…

Can anyone comment why you can only use the verbose flag if you use the full path of time? time -v ls does not work but /usr/bin/time -v ls does? I don't have enough knowledge of either linux applications or bash to know whats happening to cause this.

This is very likely because without the full path your shell is using the `time` builtin function of your shell as opposed to using the binary.

The shell's builtin keyword for `time` is more limited in nature than the full `time` binary. This is true of a number of other common unix commands as well, e.g. `echo`. The manpage for your shell should describe the builtins functions.

Re: Benchmarking shell pipelines and the Unix “tools” philosophy

#50
post #47
post #4

Thanks for this! Another nice thing about /usr/bin/time is the --verbose flag which gives: Command being timed: "ls" User time (seconds): 0.00 System time (seconds): 0.00 Percent of CPU this job got: 0% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00 Average shared text size (kbytes): 0 Average unshared data size (kbytes): 0 Average stack size (kbytes): 0 Average total size (kbytes): 0 Maximum resident set size…

Can anyone comment why you can only use the verbose flag if you use the full path of time? time -v ls does not work but /usr/bin/time -v ls does? I don't have enough knowledge of either linux applications or bash to know whats happening to cause this.

The full path calls a GNU tool, the other calls your shell's builtin function.
Post reply on HN