J'ai toujours pensé que le seul avantage de l'utilisation de dash au lieu de bash était que dash était plus petit et que, par conséquent, de nombreuses instances de dash commenceraient plus rapidement au démarrage.
Cependant, j'ai effectué des recherches et découvert que certaines personnes effectuaient la migration de tous leurs scripts dans l'espoir qu'elles fonctionneraient plus vite. J'ai également trouvé cela dans l'article DashAsBinSh dans le wiki d'Ubuntu:
La principale raison de changer de shell par défaut était l' efficacité . bash est un excellent shell complet convenant à une utilisation interactive; En effet, c'est toujours le shell de connexion par défaut. Cependant, son démarrage et son fonctionnement sont plutôt volumineux et lents par rapport à dash.
De nos jours, j'utilise beaucoup de scripts bash pour beaucoup de choses sur mon système, et le problème est que j'ai un script particulier que je lance en permanence, 24 heures sur 24, 7 jours sur 7, qui engendre environ 200 enfants et qui réchauffe mon ordinateur 10 ° C plus qu'en usage normal.
C'est un script assez volumineux avec beaucoup de bashismes, donc le portage sur POSIX ou sur un autre shell prendrait beaucoup de temps (et POSIX n'a pas vraiment d'importance pour un usage personnel), mais il serait utile que je réduise un peu cette tâche. L'utilisation du processeur. Je sais qu'il y a aussi d'autres choses à considérer, comme appeler un binaire externe comme sed
pour un simple bashisme comme ${foo/bar}
, ou à la grep
place de =~
.
TL; DR est vraiment plus lent à démarrer et à fonctionner par rapport à dash? Existe-t-il d'autres shell Unix plus efficaces que bash?
la source
[
devrait également être un intégré.bash
l'habitude d'être très lent. Il a fait beaucoup de progrès récemment, mais pour la plupart des choses, il est encore plus lent que la plupart des autres obus.[ "$foo" != "${foo#*bar}" ]
gère votre chose grep. Et lased
chose:while [ "$foo" != "${foo#*bar}" ]; do s=$s${foo%%bar*} foo=${foo#*bar} ; done ; foo=$s$foo
. Vous pouvez mettre l'une ou l'autre chose dans une fonction.Réponses:
SHELL SEQ:
Un moyen utile d’évaluer les performances d’un shell consiste probablement à effectuer de manière répétitive de très petites évaluations simples. Je pense qu’il est important, non seulement de boucler, mais de boucler une entrée , car un shell doit lire
<&0
.Je pensais que cela compléterait les tests déjà publiés par @cuonglm, car il montre les performances d'un processus shell une fois invoquées, par opposition à la sienne, qui montre la rapidité avec laquelle un processus shell se charge. De cette façon, entre nous, nous couvrons les deux côtés de la médaille.
Voici une fonction pour faciliter la démo:
Il incrémente une variable une fois par nouvelle ligne ou, dans le cas d'une légère optimisation, s'il le peut, il incrémente 50 fois par nouvelle ligne. Chaque fois que la variable est incrémentée, elle est imprimée
stdout
. Cela se comporte beaucoup comme une sorte deseq
croixnl
.Et pour que ce soit très clair, voici une
set -x;
sortie tronquée après l'avoir insérée juste avanttime
dans la fonction ci-dessus:Donc, chaque shell s'appelle d'abord comme:
... pour générer l'entrée qu'il devra boucler lorsqu'il lira
3<<\SCRIPT
- ou quand lecat
fera quand même. Et de l’autre côté,|pipe
il s’appelle encore comme:Donc, mis à part l'appel initial à
env
(car ilcat
est en fait appelé à la ligne précédente) ; aucun autre processus n'est appelé à partir du moment où il est appelé jusqu'à ce qu'il se termine. Au moins, j'espère que c'est vrai.Avant les chiffres ...
Je devrais prendre quelques notes sur la portabilité.
posh
n'aime pas$((n=n+1))
et insiste sur$((n=$n+1))
mksh
n'a pasprintf
intégré dans la plupart des cas. Les tests antérieurs avaient beaucoup de retard - il était invoquant/usr/bin/printf
pour chaque course. D'où ce quiecho -n
précède.peut-être plus que je m'en souvienne ...
Quoi qu'il en soit, aux chiffres:
Ça va les avoir tous d'un coup ...
ARBITRARY = Peut-être OK?
Néanmoins, il s’agit d’un test plutôt arbitraire, mais il teste la lecture des entrées, l’évaluation arithmétique et l’expansion des variables. Peut-être pas complet, mais peut-être près de là.
EDIT de Teresa e Junior : @mikeserv et moi avons effectué de nombreux autres tests (voir notre chat pour plus de détails), et nous avons constaté que les résultats pourraient être résumés comme suit:
grep
,sed
,sort
, etc., qui ne sont pas autant de fonctionnalités que la GNU utilisée utilitaires, mais peut faire le travail autant.la source
4.2.37(1)-release
de Debian et4.2.45(2)-release
d'un LiveCD Porteus (Slackware). Sansnull=
, au lieu de sortir des nombres, cela fonctionne comme si j’appuyais sur Entrée de façon continue, puis je dois tuer bash avec SIGKILL .bash --posix
, en vain.zsh
.zsh
va le détournertty
et bien, il va lancer un shell interactif. Je m'attends à ce quebash
nous fassions de même - c'est pourquoi je veille à ne pas appeler que son--posix
lien. Je peux le faire faire ce que vous attendez pour la plupart d'entre eux, mais cela peut représenter plus de travail que sa valeur. Appelez-vousbash
ou appelez -voussh
?Laissons faire un point de repère.
Avec
bash
:Avec
dash
:Chaque itération commence seulement un shell et ne fait rien avec l'opérateur no-op - deux points , puis quitte.
Comme le montre le résultat, il
dash
est extrêmement rapidebash
au démarrage.dash
est plus petit et dépend d'une bibliothèque moins partagée quebash
:Il s’agit d’une opération de démarrage. Laissons faire un autre repère:
Avec un test simple
1 = 1
,dash
toujours beaucoup plus rapide quebash
.la source
seq 1 100000
devrait êtreseq 1 1000
?dash
cas de test c'est seulementseq 1 1000
?1000
pour le démarrage et1000000
pour fonctionner, réparé.Voici quelques timings de démarrage de divers shells dans un UNIX certifié (Mac OS X 10.10.3). J'ai réécrit le test pour utiliser tcsh afin de contrôler les boucles, de sorte que le shell testé ne soit pas celui qui contrôle les boucles. Pour chaque shell, la boucle est exécutée cinq fois avant le chronométrage, afin de s'assurer que l'exécutable du shell et les scripts sont en cache.
Comme vous pouvez le constater, il n'y a pas de gagnant net, mais un perdant définitif. Quoi qu'il en soit, bash 4 est nettement plus lent que bash 3. Dash fonctionne bien, mais étant donné que ksh93 est maintenant une source ouverte, il n'y a aucune raison de ne pas l'utiliser pour tout (des excuses si je comprends mal les subtilités en matière de licence): ksh93 est rapide, solide et une norme de facto dans UNIX-land (si ce n’est pas dans GNU / Linux-land); il fournit un sur-ensemble des fonctionnalités du shell POSIX (autant que je sache, le shell POSIX était basé sur ksh88); il est égal à bash en tant que shell interactif, bien qu'en retard par rapport à tcsh. Et le perdant est bien sûr zsh.
la source
Il y a trop de cas tests inéquitables dans de nombreuses réponses ici. Si vous testez deux shells, utilisez la syntaxe correcte pour chacun d'eux. Et à Bash, les doubles supports sont beaucoup plus rapides et plus fiables que les supports simples, ce qui réduit considérablement la différence de vitesse. Également utiliser des bashismes optimisés et ces différences de vitesse sont plus moins aussi. Sur mon système, bash fonctionne comme un diable, avec un usage intensif des bashismes. Et les équivalents posix en tiret sont plus lents ici. Ce n’est pas correct que dash soit toujours plusieurs fois plus rapide que bash. Il est vraiment injuste de comparer les lignes de commande posix dans les deux cas, qui peut toujours être le plus rapide. À mon avis, Posix est lourdement obsolète. Et en termes de compatibilité, il est vraiment difficile de trouver des systèmes pertinents de nos jours, ils n’ont pas utilisé de shell bash.
Une bonne comparaison est la suivante: utiliser la meilleure ligne de commande possible dans chaque shell pour terminer un travail spécifique. Pas seulement la même ligne de commande, lorsqu'un seul shell a vraiment un avantage ici. Des comparaisons comme celle-ci ne sont pas fiables et ne montrent pas les performances réelles des concurrents. Je vois dans mon travail quotidien, quel shell est plus rapide dans de nombreux cas d'utilisation.
Par exemple, pour remplacer tous les
a
caractères dans la chaîne avec desb
personnages, en bash vous pouvez écrire"${varname//a/b}"
tout au tableau de bord , vous devez appeler outil externe comme ceci:"$(echo "$varname" | sed 's/a/b/g')"
. Si vous devez le répéter quelques centaines de fois, l’utilisation du basisme peut vous donner une accélération 2x.la source