GNU/Linux >> Linux Esercitazione >  >> Linux

Qual è il modo più veloce per eseguire uno script?

I terminali in questi giorni sono più lenti di una volta, principalmente perché le schede grafiche non si preoccupano più dell'accelerazione 2D. Quindi, in effetti, la stampa su un terminale può rallentare uno script, in particolare quando è coinvolto lo scorrimento.

Di conseguenza ./script.sh è più lento di ./script.sh >script.log , che a sua volta è più lento di /script.sh >/dev/null , perché questi ultimi comportano meno lavoro. Tuttavia, se questo fa abbastanza differenza per qualsiasi scopo pratico dipende dalla quantità di output prodotta dallo script e dalla velocità. Se il tuo script scrive 3 righe ed esce, o se stampa 3 pagine ogni poche ore, probabilmente non hai bisogno di preoccuparti dei reindirizzamenti.

Modifica: Alcuni benchmark rapidi (e completamente interrotti):

  • In una console Linux, 240x75:

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

    $ time (for i in {1..100000}; do echo $i 01234567890123456789012345678901234567890123456789; done)
    real    0m1.367s
    user    0m0.507s
    sys     0m0.104s
    
  • Reindirizza a un file, su un disco Samsung SSD 850 PRO da 512 GB:

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

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

Sarei stato istintivamente d'accordo con la risposta di Sato Katsura; ha senso. Tuttavia, è abbastanza facile da testare.

Ho provato a scrivere un milione di righe sullo schermo, scrivere (aggiungere) a un file e reindirizzare a /dev/null . Ho testato ciascuno di questi a turno, quindi ho fatto cinque repliche. Questi sono i comandi che ho usato.

$ 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)

Ho quindi tracciato i tempi totali di seguito.

Come puoi vedere, le presunzioni di Sato Katsura erano corrette. Secondo la risposta di Satō Katsura, dubito anche che il fattore limitante sarà l'output, quindi è improbabile che la scelta dell'output abbia un effetto sostanziale sulla velocità complessiva della sceneggiatura.

FWIW, la mia risposta originale aveva un codice diverso, che aveva l'aggiunta del file e /dev/null reindirizzare all'interno il ciclo.

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

Come sottolinea John Kugelman nei commenti, questo aggiunge molto sovraccarico. Allo stato attuale della domanda, questo non è davvero il modo giusto per testarlo, ma lo lascerò qui poiché mostra chiaramente il costo della riapertura ripetuta di un file dall'interno lo script stesso.

In questo caso, i risultati sono invertiti.


Un altro modo per velocizzare uno script è usare un interprete di shell più veloce. Confronta le velocità di un POSIX ciclo occupato, eseguito sotto 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
    

    Uscita:

    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
    

    Uscita:

    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
    

    Uscita:

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

Un sottoinsieme di comandi in bash e ksh sono retrocompatibili con tutti i comandi in dash . Un bash script che utilizza solo comandi in quel sottoinsieme dovrebbe funzionare con dash .

Alcuni bash gli script che utilizzano nuove funzionalità possono essere convertiti in un altro interprete. Se bash script fa molto affidamento sulle funzionalità più recenti, potrebbe non valerne la pena -- alcune nuovo bash le funzionalità sono miglioramenti che sono sia più facili da codificare che più efficiente, (nonostante bash essendo generalmente più lento), in modo che il dash equivalente, (che potrebbe comportare l'esecuzione di molti altri comandi), sarebbe più lento.

In caso di dubbio, esegui un test...


Linux
  1. Ottieni lo script da eseguire di nuovo se l'input è Sì?

  2. Il modo più veloce per estrarre un ISO?

  3. A che scopo serve il Colon Builtin ':'?

  4. Qual è il modo migliore per garantire che sia in esecuzione solo un'istanza di uno script Bash?

  5. Come eseguire uno script sul blocco/sblocco dello schermo?

Qual è l'uso di $# in Bash

Qual è il modo più veloce per combinare due o più file in Linux?

Qual è il modo più veloce per spostare un milione di immagini da una directory all'altra in Linux?

Qual è il modo migliore per imparare SELinux?

qual è il significato di 1 alla fine dello script awk

Qual è il modo più veloce per rimuovere tutti i file e le sottocartelle in una directory?