Pages

mercredi 29 mai 2013

optimisation de script bash en limitant l'ouverture de processus

Ce qui prend du temps pour un script shell est le nombre de programmes appelés et donc, le nombre de processus créés.

Le meilleur moyen d’accélérer un script est de passer par les builtins et limiter les boucles ouverture/fermeture de programme.
En fait, dans certain cas, on pourrait avoir une commande qui lit sur l'entrée standard et retourne un résultat ; un peu comme bc. C'est là que les coprocess viennent à la rescousse :).

Un coprocess est un sous-shell exécuté de façon asynchrone et fournissant les tubes d'entrée/sortie. Ceux-ci sont accessibles via COPROC[1] et COPROC[2].

Dû coup, avec bc, la méthode est d'écrire dans un tube et lire dans l'autre. Comme la lecture est bloquante, le script va attendre que bc retourne le résultat.
Et voilà l'ouverture d'un programme remplacé par une lecture/écriture.

Par exemple, un petit programme qui lit un fichier contenant des opérations mathématiques et les affiches suivies du résultat.

#!/bin/bash
[ -z "$1" ] && echo $0: file >&2 && exit 1

#coprocess de bc avec la sortie d'erreur redirigée vers la sortie standard
coproc bc 2>&1

while read l; do
 echo "$l" >&${COPROC[1]} # écrire dans le coprocess
 read result <&${COPROC[0]} # réception du résultat
 echo $l = $result
done < "$1"

Sans coproc, la boucle est plus simple mais un processus sera ouvert pour chaque ligne du fichier, ce qui est particulièrement coûteux.

#sans coproc
while read l; do
 echo "$l" = `echo "$l" | bc 2>&1`
done < "$1"

À tester avec par exemple un fichier de calcul comme celui-ci

2+3
2+3*9
23*9
23s*9
3*9

Aucun commentaire: