Für den Vergleich der Laufzeiten von Skripten zwischen verschiedenen Shells empfehlen einige SE-Antworten die Verwendung bash
des integrierten time
Befehls wie folgt:
time bash -c 'foo.sh'
time dash -c 'foo.sh'
... usw. , damit jede Shell getestet werden kann. Solche Benchmarks eliminieren nicht die Zeit, die jede Shell benötigt, um sich selbst zu laden und zu initialisieren . Angenommen, beide oben genannten Befehle wurden auf einem langsamen Gerät mit der Lesegeschwindigkeit einer frühen Diskette gespeichert (124 KB / s) dash
(eine ausführbare Datei mit ~ 150 KB), die etwa 7x schneller als die Shell bash
( ~ 1 MB ) geladen würde Die Ladezeit würde die time
Zahlen verzerren - die Vorladezeiten dieser Schalen sind für die Messung der Laufzeiten foo.sh
unter jeder Schale nach dem Laden der Schalen irrelevant .
Was ist das beste tragbare und allgemeine Dienstprogramm für das Skript-Timing, das in jeder Shell ausgeführt werden kann? Der obige Code würde also ungefähr so aussehen:
bash -c 'general_timer_util foo.sh'
dash -c 'general_timer_util foo.sh'
NB: keine Shell integrierten time
Befehle, da keine portabel oder allgemein sind.
Besser noch, wenn der Util auch die Zeit messen kann, die die internen Befehle und Pipelines einer Shell benötigen, ohne dass der Benutzer sie zuerst in ein Skript einbinden muss. Eine künstliche Syntax wie diese würde helfen:
general_timer_util "while read x ; do echo x ; done < foo"
Einige Muscheln time
können das schaffen. Zum Beispiel bash -c "time while false ; do : ; done"
funktioniert. Um zu sehen, was auf Ihrem System funktioniert (und was nicht), versuchen Sie Folgendes:
tail +2 /etc/shells |
while read s ; do
echo $s ; $s -c "time while false ; do : ; done" ; echo ----
done
/usr/bin/time
?Antworten:
Sie sollten beachten, dass dies
time
von POSIX angegeben wird und AFAICT die einzige Option, die POSIX erwähnt (-p
), von verschiedenen Shells korrekt unterstützt wird:quelle
time
. Es ist vergleichbar damit, Sprinter ihre eigene Zeit auf 100 m einzeln messen zu lassen, anstatt dies mit einer Uhr gleichzeitig zu tun. Dies ist offensichtlich ein Trottel, aber immer noch ...time
nicht portabel sind. es scheint tragbar zu sein. (Ich stimme jedoch Ihrem Punkt zur Vergleichbarkeit zu)dash -c 'time -p while false ; do : ; done'
zurückkehrt „Zeit: kann nicht ausgeführt werden, während: Keine solche Datei oder das Verzeichnis <cr> Befehl mit Nicht-Null - Status 127 beendet“ Fehlern.Ich benutze den GNU-
date
Befehl, der einen hochauflösenden Timer unterstützt:Und dann nenne ich das Skript so:
Die Ausgabeeinheit ist in Millisekunden angegeben.
quelle
date
speziell GNU erfordert .START
und "END
eingestellt". Dies würde sich offensichtlich auf Ihr Ergebnis auswirken. Keine Ahnung, wie genau Sie es brauchen und ob es in Ihrem Fall wichtig ist, aber wie gesagt, etwas, das Sie beachten sollten. (Unterhaltsame Geschichte: Ich kenne eine Software, bei der genau dies zu unerwartet negativen Ergebnissen führte - sie wurde zur Durchsatzberechnung verwendet - und die dann einige DingeDas
time
Dienstprogramm ist in der Regel in die Schale eingebaut, wie Sie vielleicht bemerkt haben, die es nutzlos als „neutral“ Timer macht.Das Dienstprogramm ist jedoch normalerweise auch als externes Dienstprogramm verfügbar
/usr/bin/time
, das durchaus zur Durchführung der von Ihnen vorgeschlagenen Timing-Experimente verwendet werden kann.quelle
foo.sh
es ausführbar ist und einen Shebang hat, wird es immer mit derselben Shell ausgeführt, und die Startzeit dieser Shell wird gezählt, sodass OP dies nicht wünscht. Wennfoo.sh
eine davon fehlt, funktioniert dies überhaupt nicht.time
habe anscheinend nur "keine eingebaute Shell " berücksichtigt. Die Shell-Startzeit muss möglicherweise separat gemessen werden.time
eingebauten Befehl. Viele Shells enthaltenbash
jedoch eintime
Schlüsselwort, mit dem Pipelines zeitlich festgelegt werden können. Um dieses Schlüsselwort zu deaktivieren, damit dertime
Befehl (im Dateisystem) verwendet werden kann, können Sie ihn wie folgt zitieren"time" foo.sh
. Siehe auch unix.stackexchange.com/search?q=user%3A22565+time+keywordHier ist eine Lösung, die:
Es gibt zwei Teile: ein kurzes C-Programm, das abgeschlossen wird
gettimeofday
, das veraltet, aber immer noch portabler als istclock_gettime
, und ein kurzes Shell-Skript, das dieses Programm verwendet, um eine Uhr mit Mikrosekundengenauigkeit zu erhalten, die beide Seiten der Beschaffung eines Skripts liest. Das C-Programm ist die einzige tragbare Methode mit minimalem Overhead, um eine Genauigkeit von weniger als einer Sekunde für einen Zeitstempel zu erzielen.Hier ist das C-Programm
epoch.c
:Und das Shell-Skript
timer
:Dies ist die Standard- Shell-Befehlssprache und
bc
und soll als Skript unter jedem POSIX-kompatiblen Shell arbeiten.Sie können dies verwenden als:
Es misst nicht die System- oder Benutzerzeit, sondern nur die nicht monotone Wanduhr. Wenn sich die Systemuhr während der Ausführung des Skripts ändert, führt dies zu falschen Ergebnissen. Wenn das System unter Last steht, ist das Ergebnis unzuverlässig. Ich denke nicht, dass etwas Besseres zwischen Muscheln tragbar sein kann.
Ein modifiziertes Timer-Skript könnte
eval
stattdessen Befehle außerhalb eines Skripts ausführen.quelle
eval
), war ich zwicken das Skript in Rabin ‚s Antwort zu enthalteneval "$@"
, so dass es Shell laufen konnte builtins on the fly.Mehrfach überarbeitete Lösung mit
/proc/uptime
unddc
/bc
/awk
in großen Teilen dank der Eingabe von agc :Nimmt offensichtlich an, dass es
/proc/uptime
existiert und eine bestimmte Form hat.quelle
/proc
Dateisystem fehlt . Ob dies ein Problem ist oder nicht, weiß ich nicht.awk
erheblich sein. Vielleichtb=$(cat /proc/uptime)
vorher, danna=$(cat /proc/uptime)
nachher, dann $ a und $ b analysieren und subtrahieren.read
besser sind alscat
, wäre dies sauberer (und etwas schneller):read before dummyvar < /proc/uptime ;sleep 2s;read after dummyvar < /proc/uptime; duration=$(dc -e "${after} ${before} - n");echo "It took $duration seconds."