当效率很重要时,从函数返回值

Håk*_*and 6 bash

在我看来,有几种方法可以从Bash函数返回一个值.

方法1:使用"local-global"变量,该变量local在调用者中定义:

func1() {
    a=10
}

parent1() {
    local a

    func1
    a=$(($a + 1))
}
Run Code Online (Sandbox Code Playgroud)

方法2:使用命令替换:

func2() {
    echo 10
}

parent2() {
    a=$(func2)
    a=$(($a + 1))
}
Run Code Online (Sandbox Code Playgroud)

使用方法1而不是方法2可以期望多少加速?

并且,我知道使用方法1中的全局变量并不是一个好的编程实践,但是由于效率考虑,它在某些时候是否合理?

tha*_*guy 5

shell 脚本中最昂贵的操作是分叉。任何涉及 fork 的操作(例如命令替换)都会比不涉及 fork 的操作慢 1-3 个数量级。

例如,这是一个直接的循环方法,它以 的形式读取一堆生成的文件,并使用file-1234去掉前缀,总共需要三个分支(命令替换+两级管道):file-sed

$ time printf "file-%s\n" {1..10000} |
     while read line; do n=$(echo "$line" | sed -e "s/.*-//"); done

real    0m46.847s
Run Code Online (Sandbox Code Playgroud)

这是一个循环,它通过参数扩展执行相同的操作,不需要分叉:

$ time printf "file-%s\n" {1..10000} |
     while read line; do n=${line#*-}; done

real    0m0.150s
Run Code Online (Sandbox Code Playgroud)

分叉版本需要的时间长 300 倍。

因此,你的问题的答案是肯定的:如果效率很重要,那么你就有充分的理由分解或替换分叉代码。

当分叉计数相对于输入是恒定的(或者它太混乱而无法使其恒定)并且代码仍然太慢时,就应该用更快的语言重写它。