Qual é a sobrecarga de usar subshells?

5

Espero que esta pergunta não seja muito genérica. Eu sou muito novo para scripts de shell e eu venho de um fundo de programação de arquitetura / não-script de computador. Tenho notado nos scripts do meu trabalho que raramente os scripts são escritos fazendo uma sub-shell em torno do script inteiro. Nos scripts que estou escrevendo, quando eu posso envolvê-lo com um sub-shell eu sou, uma vez que ele impede de mexer com outros scripts que chamam meu (apenas no caso). Isso não é uma prática comum devido a alguma sobrecarga associada a essa abordagem? Estou com dificuldade em encontrar isso online.

Exemplo:

#!/bin/bash
( #Start of subshell
echo "Some stuff here"
) #End of subshell
    
por LinuxLearner 19.05.2016 / 23:13

2 respostas

3

Subshells têm sobrecarga.

No meu sistema, o custo mínimo do fork-exec (quando você executa um programa a partir do disco quando o arquivo não está frio) é de cerca de 2ms e 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 exec ed. Se as subshells forem mantidas razoavelmente baixas, 1ms é bastante insignificante em programas voltados para humanos. Eu acredito que os seres humanos não podem perceber nada que aconteça mais rápido do que 50ms (e demorará para que os intérpretes modernos de linguagem de script iniciem (eu estou falando python e ruby em rvm aqui) com o mais recente nodejs ocupando 100ms ).

No entanto, soma-se com loops e, em seguida, você pode querer substituir, por exemplo, o padrão de bactick ou $() , em que return de uma função é imprimida para stdout para o shell pai para catpure com bashisms como printf -v (ou use um programa externo rápido para processar todo o lote).

O pacote de conclusão do bash especificamente evita esse custo de subshell retornar via nomes de variáveis passadas usando uma técnica descrita em link

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 dar uma boa estimativa do que seus sistemas fork -ing sobrecarga é.

    
por 19.05.2016 / 23:31
0

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

No entanto, este exemplo realmente atinge os comandos home - comandos nativos vs 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     
    
por 30.10.2018 / 19:16