使用子 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在這裡說的是 rubyrvm​​ )與最新的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     

相關內容