We all know that our shell of choice (c'on, admit it :-)) is "too big and too slow" (quote from its manpage). But I was surprised to see *how* slow it was for this particular operation:
Update: Thanks to an observing commenter I had to find out that 'expr' is NOT a shell builtin but a simple binary. I always wondered *if* it was a shell builtin and always wondered if scripts with 'expr' would be portable and all but I never got around to do just 'which expr'. Damn. Anyway, here are the updated results now. Thanks again Roland for pointing this out! The gap between bash and ksh is not so big any more, although it's still visible:
# cat count.sh i=1 while [ "$i" -lt 10000000 ]; do ((i++)) done # for i in ksh zsh pdksh mksh bash; do (echo "SHELL: $i"; time $i count.sh); done SHELL: ksh real 0m45.196s user 0m44.676s sys 0m0.070s SHELL: zsh real 1m13.755s user 1m5.651s sys 0m7.402s SHELL: pdksh real 1m7.300s user 1m6.013s sys 0m0.092s SHELL: mksh real 1m8.922s user 1m8.013s sys 0m0.091s SHELL: bash real 3m10.721s user 3m0.016s sys 0m6.372sThis was done with ksh from AT&T Research (1993-12-28), zsh 4.3.4, PDKSH v5.2.14, MIRBSD KSH R32 and GNU bash 3.2.39(1) on a MacMini.
Update #2: as pointed out in the comment section, "(())" should be faster, so let's try again:
$ cat count.sh i=1 while (( i++ < 10000000 )); do : done $ for i in ksh zsh pdksh mksh bash; do echo "SHELL: $i"; time $i count.sh; done SHELL: ksh real 1m59.642s user 1m58.340s sys 0m0.012s SHELL: zsh real 3m34.747s user 3m4.588s sys 0m25.616s SHELL: pdksh real 4m15.224s user 4m10.056s sys 0m0.028s SHELL: mksh real 4m48.835s user 4m43.480s sys 0m0.036s SHELL: bash real 10m9.914s user 9m52.724s sys 0m4.072sThis was done with ksh-93s+ from AT&T Research (2008-01-31), zsh 4.3.10, PDKSH v5.2.14, MIRBSD KSH R39c and GNU bash 4.1.5(1) on a PowerBook G4 (M9691LL/A) (throttled to 750MHz).