虽然我同意其他评论者的观点,即bash本身很慢,但我刚刚在这里执行了一些测试来检查差异。平台是Ubuntu 10.10,运行在一台较慢的机器上。没有并行运行的其他进程。
CASE所需时间少于一半,这相当惊人:
user@machine:~$ time for i in {1..1000000}; do if [ "$i" == "45" ]; then echo $i; elif [ "$i" == "50" ]; then echo $i; fi; done
45
50
real 0m22.154s
user 0m21.750s
sys 0m0.380s
user@machine:~$ time for i in {1..1000000}; do case "$i" in "45") echo $i;; "50") echo $i;; esac; done
45
50
real 0m10.286s
user 0m10.230s
sys 0m0.040s
重复实验,但加入第三个比较对象:
user@machine:~$ time for i in {1..1000000}; do if [ "$i" == "45" ]; then echo $i; elif [ "$i" == "50" ]; then echo $i; elif [ "$i" == "6000" ]; then echo $i; fi; done
45
50
6000
real 0m32.602s
user 0m32.070s
sys 0m0.510s
user@machine:~$ time for i in {1..1000000}; do case "$i" in "45") echo $i;; "50") echo $i;; "6000") echo $i;; esac; done
45
50
6000
real 0m13.553s
user 0m13.520s
sys 0m0.010s
看起来IF语句会重复比较3次,而CASE语句只做一次比较,这可能解释了为什么CASE几乎是恒定的而IF似乎需要与比较次数成正比的时间。
现在检查建议的[[ $i == 45 ]]:
user@machine:~$ time for i in {1..1000000}; do if [[ $i == 45 ]]; then echo $i; elif [[ $i == 50 ]]; then echo $i; elif [[ $i == 6000 ]]; then echo $i; fi; done
45
50
6000
real 0m15.127s
user 0m15.090s
sys 0m0.010s
user@machine:~$ time for i in {1..1000000}; do case $i in 45) echo $i;; 50) echo $i;; 6000) echo $i;; esac; done
45
50
6000
real 0m9.966s
user 0m9.940s
sys 0m0.010s
再说一遍,CASE更快,但并不是那么快。
为了尝试确定循环本身浪费的时间,让我们试着几乎什么也不运行:
user@machine:~$ time for i in {1..1000000}
real 0m5.095s
user 0m5.070s
sys 0m0.010s