Ich war immer der Meinung, dass der einzige Vorteil der Verwendung von dash anstelle von bash darin besteht, dass dash kleiner ist und daher viele Instanzen von dash beim Booten schneller gestartet werden.
Aber ich habe einige Nachforschungen angestellt und festgestellt, dass einige Leute all ihre Skripte migrieren, um in der Hoffnung, dass sie schneller laufen, zu stürzen. Dies fand ich auch im Artikel DashAsBinSh im Ubuntu-Wiki:
Der Hauptgrund für den Wechsel der Standard-Shell war die Effizienz . bash ist eine exzellente Shell mit vollem Funktionsumfang, die für den interaktiven Gebrauch geeignet ist. In der Tat ist es immer noch die Standard-Login-Shell. Es ist jedoch im Vergleich zum Armaturenbrett ziemlich groß und langsam in Betrieb zu nehmen und zu betreiben .
Heutzutage verwende ich viele Bash-Skripte für viele Dinge auf meinem System, und mein Problem ist, dass ich ein bestimmtes Skript habe, das ständig rund um die Uhr ausgeführt wird und rund 200 Kinder hervorbringt, die zusammen meinen Computer um 10 ° erwärmen C mehr als im normalen Gebrauch.
Es ist ein ziemlich großes Skript mit vielen Bashismen, so dass das Portieren auf POSIX oder eine andere Shell sehr zeitaufwendig wäre (und POSIX ist für den persönlichen Gebrauch eigentlich nicht von Bedeutung), aber es lohnt sich, wenn ich etwas davon reduzieren könnte CPU auslastung. Ich weiß, dass es auch andere Dinge zu beachten gibt, wie das Aufrufen einer externen Binärdatei wie sed
für einen einfachen Bashismus wie ${foo/bar}
oder grep
anstelle von =~
.
TL; DR ist wirklich langsamer zu starten und im Vergleich zu Dash zu betreiben ? Gibt es andere Unix-Shells, die effizienter sind als Bash?
quelle
[
sollte auch eingebaut sein.bash
war früher sehr langsam. Es hat in letzter Zeit große Fortschritte gemacht, aber für die meisten Dinge ist es immer noch langsamer als die meisten anderen Shells.[ "$foo" != "${foo#*bar}" ]
kümmert sich um deine grep Sache. Und diesed
Sache:while [ "$foo" != "${foo#*bar}" ]; do s=$s${foo%%bar*} foo=${foo#*bar} ; done ; foo=$s$foo
. Sie können beides in eine Funktion einfügen.Antworten:
SHELL SEQ:
Wahrscheinlich ist es ein nützliches Mittel, die Leistung einer Shell zu messen, sehr kleine, einfache Auswertungen, die wiederholt durchgeführt werden. Ich denke, es ist wichtig, nicht nur eine Schleife auszuführen, sondern eine Schleife über die Eingabe auszuführen , da eine Shell lesen muss
<&0
.Ich dachte, dies würde die bereits veröffentlichten Tests von @cuonglm ergänzen , da es die Leistung eines einzelnen Shell-Prozesses zeigt, wenn er einmal aufgerufen wurde, im Gegensatz zu seinem, der zeigt, wie schnell ein Shell-Prozess geladen wird, wenn er aufgerufen wird. Auf diese Weise decken wir beide Seiten der Medaille ab.
Hier ist eine Funktion, um die Demo zu erleichtern:
Es erhöht eine Variable entweder einmal pro Zeilenumbruch oder, als leichte Optimierung, um das 50-fache pro Zeilenumbruch. Jedes Mal, wenn die Variable inkrementiert wird, wird auf gedruckt
stdout
. Es verhält sich wie eine Artseq
Kreuznl
.Und um ganz klar zu machen, was es tut - hier ist eine abgeschnittene
set -x;
Ausgabe, nachdem Sie sie direkt zuvortime
in die obige Funktion eingefügt haben:So heißt jede Shell zuerst:
... um die Eingabe zu generieren, die beim Einlesen durchlaufen werden muss
3<<\SCRIPT
- odercat
zumindest wann . Und andererseits|pipe
nennt es sich wieder so:Also abgesehen von dem ersten Aufruf an
env
(weilcat
in der vorherigen Zeile tatsächlich aufgerufen wird) ; Vom Zeitpunkt des Aufrufs bis zum Beenden werden keine anderen Prozesse aufgerufen. Zumindest hoffe ich, dass das stimmt.Vor den Zahlen ...
Ich sollte ein paar Anmerkungen zur Portabilität machen.
posh
mag nicht$((n=n+1))
und besteht darauf$((n=$n+1))
mksh
hatprintf
in den meisten Fällen kein eingebautes. Frühere Tests hatten viel Nachholbedarf - es wurde/usr/bin/printf
für jeden Lauf aufgerufen . Daher dasecho -n
Obige.vielleicht mehr, als ich mich erinnere ...
Sowieso zu den Zahlen:
Das bringt sie alle auf einen Streich ...
ARBITRARY = MÖGLICHERWEISE OK?
Dies ist immer noch ein eher willkürlicher Test, der jedoch Leseeingaben, arithmetische Auswertungen und Variablenerweiterungen testet. Vielleicht nicht umfassend, aber möglicherweise in der Nähe von dort.
EDIT von Teresa e Junior : @mikeserv und ich haben viele andere Tests durchgeführt ( Einzelheiten finden Sie in unserem Chat ), und wir haben festgestellt, dass die Ergebnisse folgendermaßen zusammengefasst werden können:
grep
,sed
,sort
usw., die als die üblicherweise verwendeten GNU nicht so viele Funktionen haben Dienstprogramme, aber kann die Arbeit so viel erledigen.quelle
4.2.37(1)-release
von Debian und4.2.45(2)-release
von einer Porteus LiveCD (Slackware) aus versucht . Ohnenull=
statt Zahlen der Ausgabe, es funktioniert , als ob ich gedrückt Return kontinuierlich, dann muss ich bash mit töten SIGKILL .bash --posix
, ohne Erfolg.zsh
.zsh
wird entführentty
und gut, es wird eine interaktive Shell starten. Ichbash
gehe davon aus, dass dies auch so sein wird - weshalb ich darauf achte, nur den--posix
Link aufzurufen . Ich kann es für die meisten von ihnen so machen, wie Sie es erwarten, aber es kann mehr Arbeit sein, als es wert ist. Rufst du anbash
oder rufst du ansh
?Machen wir einen Benchmark.
Mit
bash
:Mit
dash
:Jede Iteration startet nur eine Shell und führt nichts mit dem Operator no-op aus - Doppelpunkt , dann beenden.
Wie das Ergebnis zeigt,
dash
ist es extrem schneller alsbash
beim Start.dash
ist kleiner und von weniger gemeinsam genutzten Bibliotheken abhängig alsbash
:Hier geht es um die Startzeit, wie wäre es mit Betrieb. Machen wir noch einen Benchmark:
Mit einfachen Test
1 = 1
,dash
noch viel schneller alsbash
.quelle
seq 1 100000
sollte seinseq 1 1000
?dash
Testfall ist es nurseq 1 1000
?1000
für den Start und1000000
für den Betrieb, behoben.Hier einige Startzeiten für verschiedene Shells unter einem zertifizierten UNIX (Mac OS X 10.10.3). Ich habe den Test neu geschrieben, um tcsh zur Steuerung der Schleifen zu verwenden, sodass die zu testende Shell nicht diejenige war, die die Schleifen steuert. Für jede Shell wird die Schleife fünfmal vor dem Timing ausgeführt, um sicherzustellen, dass sich die ausführbare Shell-Datei und die Skripte im Cache befinden.
Wie Sie sehen, gibt es keinen eindeutigen Gewinner, aber einen definitiven Verlierer. Jedenfalls ist bash 4 deutlich langsamer als bash 3. Dash bietet eine gute Leistung, aber da ksh93 jetzt Open Source ist, gibt es keinen wirklichen Grund, es nicht für alles zu verwenden (entschuldige mich, wenn ich irgendwelche Lizenzierungsprobleme missverstehe): ksh93 ist schnell, solide , und ein De-facto-Standard in UNIX-Land (wenn nicht in GNU / Linux-Land); es bietet eine Obermenge der POSIX-Shell-Funktionalität (soweit ich weiß, basierte die POSIX-Shell auf ksh88); es ist gleichbedeutend mit bash als interaktive Shell, obwohl es im Vergleich zu tcsh hinterherhinkt. Und der Verlierer ist natürlich zsh.
quelle
Es gibt hier zu viele unfaire Testfälle in vielen Antworten. Wenn Sie zwei Shells testen, verwenden Sie für jede die richtige Syntax. Und in bash sind Doppelklammern viel schneller und zuverlässiger als Einzelklammern, so dass es überhaupt keinen Geschwindigkeitsunterschied gibt. Verwenden Sie auch optimierte Bashismen, um die Geschwindigkeitsunterschiede zu verringern. Auf meinem System läuft die Bash wie die Hölle, mit starkem Gebrauch von Bashismen. Und Posix-Äquivalente im Strich sind hier langsamer. Dies ist nicht korrekt, da der Bindestrich immer um ein Vielfaches schneller ist als die Bash. Wirklich ist es ziemlich unfair, Posix-Befehlszeilen in beiden zu vergleichen, wobei Strich immer der schnellste sein kann. Meiner Meinung nach ist posix stark veraltet. Und was die Kompatibilität angeht, ist es heutzutage sehr schwierig, relevante Systeme zu finden. Sie verwendeten keine Bash-Shell.
Ein guter Vergleich besteht darin, die bestmögliche Befehlszeile in jeder Shell zu verwenden, um einen bestimmten Job zu beenden. Nicht nur genau die gleiche Kommandozeile, wenn hier wirklich nur eine Shell einen Vorteil hat. Derartige Vergleiche sind unzuverlässig und zeigten nicht die tatsächliche Leistung der Wettbewerber. Ich sehe bei meiner täglichen Arbeit, welche Shell in vielen Anwendungsfällen schneller ist.
Um zum Beispiel alle ersetzen
a
Zeichen in Zeichenkette mitb
Zeichen, in bash Sie können schreiben ,"${varname//a/b}"
während in dash Sie externes Tool wie folgt verlangen:"$(echo "$varname" | sed 's/a/b/g')"
. Wenn Sie es ein paar hundert Mal wiederholen müssen - mit Bashismus können Sie 2x beschleunigen.quelle