GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Was ist der schnellste Weg, um ein Skript auszuführen?

Terminals sind heutzutage langsamer als früher, hauptsächlich weil sich Grafikkarten nicht mehr um 2D-Beschleunigung kümmern. Das Drucken auf einem Terminal kann also tatsächlich ein Skript verlangsamen, besonders wenn es um Scrollen geht.

Folglich ./script.sh ist langsamer als ./script.sh >script.log , was wiederum langsamer als /script.sh >/dev/null ist , weil letztere weniger Arbeit bedeuten. Ob dies jedoch für praktische Zwecke einen ausreichenden Unterschied macht, hängt davon ab, wie viel und wie schnell Ihr Skript ausgegeben wird. Wenn Ihr Skript 3 Zeilen schreibt und sich beendet, oder wenn es alle paar Stunden 3 Seiten druckt, brauchen Sie sich wahrscheinlich nicht um Weiterleitungen zu kümmern.

Bearbeiten: Einige schnelle (und völlig kaputte) Benchmarks:

  • In einer Linux-Konsole 240 x 75:

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

    $ time (for i in {1..100000}; do echo $i 01234567890123456789012345678901234567890123456789; done)
    real    0m1.367s
    user    0m0.507s
    sys     0m0.104s
    
  • Umleitung zu einer Datei auf einer Samsung SSD 850 PRO 512 GB Festplatte:

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

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

Ich hätte Satō Katsuras Antwort instinktiv zugestimmt; es ergibt Sinn. Es ist jedoch einfach zu testen.

Ich habe getestet, eine Million Zeilen auf den Bildschirm zu schreiben, in eine Datei zu schreiben (anzuhängen) und zu /dev/null umzuleiten . Ich habe diese nacheinander getestet und dann fünf Wiederholungen durchgeführt. Dies sind die Befehle, die ich verwendet habe.

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

Ich habe dann die Gesamtzeiten unten aufgetragen.

Wie Sie sehen können, waren Satō Katsuras Vermutungen richtig. Gemäß der Antwort von Satō Katsura bezweifle ich auch, dass der begrenzende Faktor die Ausgabe sein wird, daher ist es unwahrscheinlich, dass die Wahl der Ausgabe einen wesentlichen Einfluss auf die Gesamtgeschwindigkeit des Skripts hat.

FWIW, meine ursprüngliche Antwort hatte einen anderen Code, an den die Datei angehängt war und /dev/null umleiten innen die Schleife.

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

Wie John Kugelman in den Kommentaren betont, fügt dies viel Overhead hinzu. So wie die Frage steht, ist dies nicht wirklich der richtige Weg, um es zu testen, aber ich belasse es hier, da es deutlich zeigt, wie viel es kostet, eine Datei wiederholt innerhalb zu öffnen das Skript selbst.

In diesem Fall werden die Ergebnisse umgekehrt.


Eine andere Möglichkeit, ein Skript zu beschleunigen, besteht darin, einen schnelleren Shell-Interpreter zu verwenden. Vergleichen Sie die Geschwindigkeiten eines POSIX Besetztschleife, läuft unter bash v4.4 , ksh v93u+20120801 , und 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
    

    Ausgabe:

    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
    

    Ausgabe:

    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
    

    Ausgabe:

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

Eine Teilmenge von Befehlen in bash und ksh sind abwärtskompatibel zu allen Befehlen in dash . Ein bash Skript, das nur Befehle in dieser Teilmenge verwendet, sollte mit dash funktionieren .

Einige bash Skripte, die neue Funktionen verwenden, können in einen anderen Interpreter konvertiert werden. Wenn der bash Skript stark auf neuere Features angewiesen ist, lohnt es sich vielleicht nicht -- einige neu bash Features sind Verbesserungen, die einfacher zu programmieren sind und effizienter, (trotz bash generell langsamer), so dass dash Äquivalent, (was die Ausführung mehrerer anderer Befehle beinhalten könnte), wäre langsamer.

Führen Sie im Zweifelsfall einen Test durch...


Linux
  1. Linux – Wie führt man ein Skript zum Sperren/Entsperren des Bildschirms aus?

  2. Der „richtige“ Weg, um zu testen, ob ein Dienst in einem Skript ausgeführt wird?

  3. Skript erneut ausführen lassen, wenn Eingabe ja ist?

  4. Was bedeutet Echo $? Tun??

  5. Der schnellste Weg, ein Iso zu extrahieren?

Was ist der beste Weg, um sicherzustellen, dass nur eine Instanz eines Bash-Skripts ausgeführt wird?

Wie verwendet man inotify richtig?

Was ist der richtige Weg, um Tabulatoren in sed einzufügen?

Was ist der schnellste Weg, um alle Dateien und Unterordner in einem Verzeichnis zu entfernen?

Was ist der sicherste und portabelste Weg, um die Echo-Binärdatei aufzurufen?

Was ist der beste Weg, um zu überprüfen, ob ein Volume in einem Bash-Skript gemountet ist?