Qual é o caminho mais rápido para executar um script?

19

Eu queria saber qual é o caminho mais rápido para executar um script, eu tenho lido que há uma diferença na velocidade entre mostrar a saída do script no terminal, redirecionando-o para um arquivo ou talvez /dev/null .

Portanto, se a saída não for importante, qual é a maneira mais rápida de fazer o script funcionar mais rápido, mesmo que seja mínimo.

bash ./myscript.sh 
-or-
bash ./myscript.sh > myfile.log
-or-
bash ./myscript.sh > /dev/null
    
por Kingofkech 12.10.2017 / 12:05

3 respostas

30

Os terminais atualmente são mais lentos do que costumavam ser, principalmente porque as placas gráficas não se importam mais com a aceleração 2D. Então, de fato, imprimir em um terminal pode atrasar um script, particularmente quando a rolagem está envolvida.

Consequentemente, ./script.sh é mais lento que ./script.sh >script.log , que por sua vez é mais lento que /script.sh >/dev/null , porque este último envolve menos trabalho. No entanto, se isso faz diferença suficiente para qualquer finalidade prática, depende da quantidade de saída que o seu script produz e da velocidade. Se o seu script escrever 3 linhas e saídas, ou se imprimir 3 páginas em intervalos de algumas horas, provavelmente não precisará se preocupar com redirecionamentos.

Editar: alguns testes de desempenho rápidos (e completamente interrompidos):

  • Em um console Linux, 240x75:

    $ time (for i in {1..100000}; do echo $i 01234567890123456789012345678901234567890123456789; done)
    real    3m52.053s
    user    0m0.617s
    sys     3m51.442s
    
  • Em um xterm , 260x78:

    $ time (for i in {1..100000}; do echo $i 01234567890123456789012345678901234567890123456789; done)
    real    0m1.367s
    user    0m0.507s
    sys     0m0.104s
    
  • Redirecionar para um arquivo, em um disco Samsung SSD 850 PRO 512GB:

     $ time (for i in {1..100000}; do echo $i 01234567890123456789012345678901234567890123456789; done >file)
     real    0m0.532s
     user    0m0.464s
     sys     0m0.068s
    
  • Redirecionar para /dev/null :

     $ time (for i in {1..100000}; do echo $i 01234567890123456789012345678901234567890123456789; done >/dev/null)
     real    0m0.448s
     user    0m0.432s
     sys     0m0.016s
    
por 12.10.2017 / 12:24
13

Eu teria concordado instintivamente com a resposta de Satō Katsura; faz sentido. No entanto, é fácil de testar.

Testei escrever um milhão de linhas na tela, escrevendo (anexando) em um arquivo e redirecionando para /dev/null . Eu testei cada um deles por sua vez, depois fiz cinco repetições. Estes são os comandos que eu usei.

$ time (for i in {1..1000000}; do echo foo; done)
$ time (for i in {1..1000000}; do echo foo; done > /tmp/file.log) 
$ time (for i in {1..1000000}; do echo foo; done > /dev/null)

Eu plotei os tempos totais abaixo.

Comovocêpodever,aspresunçõesdeSatōKatsuraestavamcorretas.DeacordocomarespostadeSatōKatsura,duvidotambémqueofatorlimitantesejaasaída,portantoéimprovávelqueaescolhadasaídatenhaumefeitosubstancialnavelocidadegeraldoscript.

FWIW,minharespostaoriginaltinhacódigodiferente,quetinhaoarquivoanexadoe/dev/nullredirectdentrodoloop.

$rm/tmp/file.log;touch/tmp/file.log;time(foriin{1..1000000};doechofoo>>/tmp/file.log;done)$time(foriin{1..1000000};doechofoo>/dev/null;done)

ComoJohnKugelmanapontanoscomentários,issoadicionamuitasobrecarga.Comoaquestãopermanece,estenãoéojeitocertodetestá-la,masdeixareiaqui,poismostraclaramenteocustodereabrirumarquivorepetidamenteapartirdodentrodopróprioscript.

Neste caso, os resultados são invertidos.

    
por 12.10.2017 / 13:47
2

Outra maneira de acelerar um script é usar um interpretador de shell mais rápido. Compare as velocidades de um loop ocupado POSIX , executado sob bash v4.4 , ksh v93u + 20120801 e dash v0.5.8 .

  1. bash :

    time echo 'n=0;while [ $n -lt 1000000 ] ; do \
                      echo $((n*n*n*n*n*n*n)) ; n=$((n+1)); 
                   done' | bash -s > /dev/null
    

    Saída:

    real    0m25.146s
    user    0m24.814s
    sys 0m0.272s
    
  2. ksh :

    time echo 'n=0;while [ $n -lt 1000000 ] ; do \
                      echo $((n*n*n*n*n*n*n)) ; n=$((n+1)); 
                   done' | ksh -s > /dev/null
    

    Saída:

    real    0m11.767s
    user    0m11.615s
    sys 0m0.010s
    
  3. dash :

    time echo 'n=0;while [ $n -lt 1000000 ] ; do \
                      echo $((n*n*n*n*n*n*n)) ; n=$((n+1)); 
                   done' | dash -s > /dev/null
    

    Saída:

    real    0m4.886s
    user    0m4.690s
    sys 0m0.184s
    

Um subconjunto de comandos em bash e ksh é compatível com versões anteriores para todos os comandos em dash . Um script bash que usa apenas comandos nesse subconjunto deve funcionar com dash .

Alguns scripts bash que usam novos recursos podem ser convertidos em outro interpretador. Se o script bash depende muito de recursos mais novos, pode não valer a pena - alguns novos recursos bash são melhorias que são mais fáceis de codificar e mais eficiente, (apesar de bash ser geralmente mais lento), de modo que o dash equivalente (que pode envolver a execução de vários outros comandos) seria mais lento.

Em caso de dúvida, execute um teste ...

    
por 18.10.2017 / 09:21

Tags