Qual é a sobrecarga do uso de subshells?

Qual é a sobrecarga do uso de subshells?

Esperamos que esta questão não seja muito genérica. Sou muito novo em scripts de shell e tenho experiência em arquitetura de computadores/programação sem scripts. Tenho notado nos scripts do meu trabalho que raramente os scripts são escritos criando um sub-shell em torno de todo o script. Nos scripts que estou escrevendo, quando consigo envolvê-lo com um sub-shell, o faço, pois evita que ele mexa com outros scripts que chamam o meu (por precaução). Esta não é uma prática comum devido a alguma sobrecarga associada a esta abordagem? Estou tendo dificuldade em encontrar isso online.

Exemplo:

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

Responder1

Subshells têm sobrecarga.

No meu sistema, o custo mínimo de fork-exec (quando você executa um programa a partir do disco quando o arquivo não está frio) é de cerca de 2mse o custo mínimo de bifurcação é de cerca de 1ms.

Com subshells, você está falando apenas do custo de bifurcação, já que nenhum arquivo precisa ser execeditado. Se os subshells forem mantidos razoavelmente baixos, 1msisso é bastante insignificante em programas voltados para humanos. Acredito que os humanos não conseguem perceber nada que acontece mais rápido do que 50ms(e esse é o tempo que tende a levar para que os intérpretes de linguagem de script modernos comecem (estou falando pythone Ruby rvmaqui) com o que nodejshá de mais novo por aí 100ms).

No entanto, ele adiciona loops, e então você pode querer substituir, por exemplo, o bacick ou $()padrão bastante comum onde você returnalgo de uma função imprimindo-o em stdout para o shell pai para catpure com bashisms como printf -v(ou use um externo rápido programa para processar todo o lote).

Oconclusão do bashpacote evita especificamente esse custo de subshell retornando por meio de nomes de variáveis ​​​​passados ​​​​usando uma técnica descrita emhttp://fvue.nl/wiki/Bash:_Passing_variables_by_reference


Comparando

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

com

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

deve fornecer uma boa estimativa de qual forké a sobrecarga do seu sistema.

Responder2

A execução do excelente código fornecido por PSkocik em meu sistema mostrou resultados insignificantes.

No entanto, este exemplo realmente atinge o alvo - comandos nativos versus comandos subshell:

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     

informação relacionada