使用子 shell 的开销是多少?

使用子 shell 的开销是多少?

希望这个问题不是太笼统。我对 shell 脚本非常陌生,并且有计算机体系结构/非脚本编程背景。我注意到我工作中的脚本很少是通过围绕整个脚本创建子 shell 来编写的。在我正在编写的脚本中,当我可以用子 shell 封装它时,我会这样做,因为它可以防止它与调用我的其他脚本混淆(以防万一)。由于与此方法相关的一些开销,这不是一种常见做法吗?我很难在网上找到这个。

例子:

#!/bin/bash
( #Start of subshell
echo "Some stuff here"
) #End of subshell

答案1

子 shell 确实有开销。

在我的系统上,最小 fork-exec 成本(当文件未冷时从磁盘运行程序时)约为2ms,最小分叉成本约为1ms

对于子 shell,您仅讨论分叉成本,因为不需要exec编辑任何文件。如果子 shell 保持合理的低水平,则1ms在面向人类的程序中可以忽略不计。我相信人类无法注意到任何比这更快的事情发生50ms(这就是现代脚本语言解释器开始(我python在这里说的是 ruby rvm​​)与最新的nodejs情况所需的时间100ms)。

但是,它确实会增加循环,然后您可能想要替换例如相当常见的 bactick 或$()模式,在该return模式中,您可以通过将函数打印到 stdout 来让父 shell 用 bashisms 捕获printf -v(或使用快速外部程序来处理整个批次)。

bash 完成包通过使用以下描述的技术通过传递的变量名返回来专门避免这种子 shell 成本http://fvue.nl/wiki/Bash:_Passing_variables_by_reference


比较

time for((i=0;i<10000;i++)); do echo "$(echo hello)"; done >/dev/null 

time for((i=0;i<10000;i++)); do echo hello; done >/dev/null 

应该可以让您很好地估计您的系统fork开销是多少。

答案2

在我的系统上运行 PSkocik 提供的优秀代码显示的结果可以忽略不计。

然而,这个例子确实很重要——本机命令与子shell命令:

MyPath="path/name.ext" 
# this takes forever
time for((i=0;i<10000;i++)); do echo "$(basename ${MyPath} )"; done >/dev/null 
#this is over 100x less time 
time for((i=0;i<10000;i++)); do echo "${MyPath##*/}"; done >/dev/null     

相关内容