在我看来,有几种方法可以从 Bash 函数返回值。
方法 1:使用"局部-全局"变量,该变量在调用方中定义为local
:
func1() {
a=10
}
parent1() {
local a
func1
a=$(($a + 1))
}
方法 2:使用命令替换:
func2() {
echo 10
}
parent2() {
a=$(func2)
a=$(($a + 1))
}
使用方法 1 比使用方法 2 可以期望多少加速?
而且,我知道像方法 1 那样使用全局变量不是好的编程实践,但是出于效率考虑,在某些时候是否可以证明是合理的?
shell 脚本中最昂贵的操作是分叉。任何涉及分叉的操作,例如命令替换,都将比没有分叉的操作慢 1-3 个数量级。
例如,这是一个循环的简单方法,它以file-1234
的形式读取一堆生成的文件,并使用sed
去除file-
前缀,总共需要三个分支(命令替换+两阶段管道):
$ time printf "file-%sn" {1..10000} |
while read line; do n=$(echo "$line" | sed -e "s/.*-//"); done
real 0m46.847s
下面是一个对参数扩展执行相同操作的循环,不需要分叉:
$ time printf "file-%sn" {1..10000} |
while read line; do n=${line#*-}; done
real 0m0.150s
分叉版本需要 300 倍的时间。
因此,你的问题的答案是肯定的:如果效率很重要,你有充分的理由分解或替换分叉代码。
当分叉计数相对于输入是恒定的(或者它太混乱而无法使其恒定)并且代码仍然太慢时,您应该用更快的语言重写它。
1肯定比方法2快得多,因为它没有任何中断(这反过来可能需要多个操作系统内核交叉才能服务)并且只有一个内存访问!!