Fatmawati Achmad Zaenuri / Shutterstock.com
Vous voulez savoir combien de temps un processus s’exécute et bien plus encore? Le Linux time
La commande renvoie des statistiques de temps, vous donnant des informations intéressantes sur les ressources utilisées par vos programmes.
le temps a beaucoup de parents
Il existe de nombreuses distributions Linux et différents systèmes d’exploitation de type Unix. Chacun d’eux a un shell de commande par défaut. Le shell par défaut le plus courant dans les distributions Linux modernes est le shell bash. Mais il y en a beaucoup d’autres, comme le shell Z (zsh) et le shell Korn (ksh).
Tous ces coques intègrent leur propre time
commande, soit en tant que intégré commande ou en tant que mot reservé. Lorsque vous tapez time
dans une fenêtre de terminal, le shell exécutera sa commande interne au lieu d’utiliser le GNU time
binaire qui est fourni dans le cadre de votre distribution Linux.
Nous voulons utiliser la version GNU de time
parce qu’il a plus options et est plus flexible.
Quelle heure va courir?
Vous pouvez vérifier quelle version fonctionnera en utilisant le type
commander. type
vous fera savoir si le shell gérera lui-même votre instruction, avec ses routines internes, ou la transmettra au binaire GNU.
dans une fenêtre de terminal, tapez le mot type
, un espace, puis le mot time
et appuyez sur Entrée.
type time
On peut voir ça dans le shell bash time
est un mot réservé. Cela signifie que Bash utilisera sontime
routines par défaut.
type time
Dans le shell Z (zsh) time
est un mot réservé, donc les routines internes du shell seront utilisées par défaut.
type time
Dans la coquille Korn time
est un mot-clé. Une routine interne sera utilisée à la place du GNU time
commander.
Exécution de la commande GNU time
Si le shell de votre système Linux a un time
vous devrez être explicite si vous souhaitez utiliser le GNU time
binaire. Vous devez soit:
- Fournissez le chemin complet vers le binaire, tel que
/usr/bin/time
. Exécutez lewhich time
commande pour trouver ce chemin. - Utilisation
command time
. - Utilisez une barre oblique inverse comme
time
.
Le which time
La commande nous donne le chemin vers le binaire.
Nous pouvons tester cela en utilisant /usr/bin/time
comme commande pour lancer le binaire GNU. Ça marche. Nous obtenons une réponse du time
commande nous indiquant que nous n’avons fourni aucun paramètre de ligne de commande pour qu’il fonctionne.
Dactylographie command time
fonctionne également, et nous obtenons les mêmes informations d’utilisation de time
. Le command
commande indique au shell d’ignorer la commande suivante afin qu’elle soit traitée en dehors du shell.
Utilisant un le caractère avant le nom de la commande équivaut à utiliser
command
avant le nom de la commande.
Le moyen le plus simple de vous assurer que vous utilisez GNU time
binaire consiste à utiliser l’option de barre oblique inverse.
time
time
time
invoque la version du temps. time
utilise le time
.
Utilisation de la commande time
Chronométrons certains programmes. Nous utilisons deux programmes appelés loop1
et loop2
. Ils ont été créés à partir de loop1.c et loop2.c. Ils ne font rien d’utile à part démontrer les effets d’un type d’inefficacité du codage.
C’est loop1.c. La longueur d’une chaîne est requise dans les deux boucles imbriquées. La longueur est obtenue à l’avance, en dehors des deux boucles imbriquées.
#include "stdio.h" #include "string.h" #include "stdlib.h" int main (int argc, char* argv[]) { int i, j, len, count=0; char szString[]="how-to-geek-how-to-geek-how-to-geek-how-to-geek-how-to-geek-how-to-geek"; // get length of string once, outside of loops len = strlen( szString ); for (j=0; j<500000; j++) { for (i=0; i < len; i++ ) { if (szString[i] == '-') count++; } } printf("Counted %d hyphensn", count); exit (0); } // end of main
C’est loop2.c. La longueur de la chaîne est obtenue à chaque fois pour chaque cycle de la boucle externe. Cette inefficacité devrait apparaître dans les délais.
#include "stdio.h" #include "string.h" #include "stdlib.h" int main (int argc, char* argv[]) { int i, j, count=0; char szString[]="how-to-geek-how-to-geek-how-to-geek-how-to-geek-how-to-geek-how-to-geek"; for (j=0; j<500000; j++) { // getting length of string every // time the loops trigger for (i=0; i < strlen(szString); i++ ) { if (szString[i] == '-') count++; } } printf("Counted %d hyphensn", count); exit (0); } // end of main
Allumons le loop1
programme et utilisation time
pour mesurer ses performances.
time ./loop1
Maintenant faisons la même chose pour loop2
.
time ./loop2
Cela nous a donné deux ensembles de résultats, mais ils sont dans un format vraiment moche. Nous pouvons faire quelque chose à ce sujet plus tard, mais choisissons quelques informations parmi les résultats.
Lorsque les programmes s’exécutent, il existe deux modes d’exécution entre lesquels ils sont commutés. Ceux-ci sont appelés et.
En bref, un processus en mode utilisateur ne peut pas accéder directement au matériel ou à la mémoire de référence en dehors de sa propre allocation. Pour avoir accès à ces ressources, le processus doit faire des requêtes au noyau. Si le noyau approuve la demande, le processus entre en exécution en mode noyau jusqu’à ce que l’exigence soit satisfaite. Le processus est ensuite repassé en exécution en mode utilisateur.
Les résultats pour loop1
dis nous que loop1
passé 0,09 seconde en mode utilisateur. Il n’a passé aucun temps en mode noyau ou le temps en mode noyau est une valeur trop faible pour être enregistrée une fois qu’elle a été arrondie vers le bas. Le temps total écoulé était de 0,1 seconde. loop1
s’est vu attribuer en moyenne 89% du temps CPU sur la durée totale de son temps écoulé.
L’inefficace loop2
programme a pris trois fois plus de temps à exécuter. Son temps total écoulé est de 0,3 seconde. La durée du temps de traitement en mode utilisateur est de 0,29 seconde. Rien ne s’inscrit en mode noyau. loop2
a reçu une moyenne de 96% du temps CPU pour la durée de son exécution.
Formatage de la sortie
Vous pouvez personnaliser la sortie de time
en utilisant une chaîne de format. La chaîne de format peut contenir du texte et des spécificateurs de format. La liste des spécificateurs de format peut être trouvé sur la page de manuel pour time
. Chacun des spécificateurs de format représente une information.
Lorsque la chaîne est imprimée, les spécificateurs de format sont remplacés par les valeurs réelles qu’ils représentent. Par exemple, le spécificateur de format pour le pourcentage de CPU est la lettre P
. Pour indiquer à time
qu’un spécificateur de format n’est pas simplement une lettre ordinaire, ajoutez-y un signe de pourcentage, comme %P
. Utilisons-le dans un exemple.
Le -f
L’option (format string) est utilisée pour indiquer time
que ce qui suit est une chaîne de format.
Notre chaîne de format va imprimer les caractères «Programme:» et le nom du programme (et tous les paramètres de ligne de commande que vous passez au programme). Le %C
Le spécificateur de format signifie «Nom et arguments de ligne de commande de la commande chronométrée». Le n
fait passer la sortie à la ligne suivante.
Il existe de nombreux spécificateurs de formats et ils sont sensibles à la casse, alors assurez-vous de les saisir correctement lorsque vous le faites vous-même.
Ensuite, nous allons imprimer les caractères « Temps total: » suivi de la valeur du temps total écoulé pour cette exécution du programme (représenté par %E
).
Nous utilisons n
pour donner une autre nouvelle ligne. Nous imprimerons ensuite les caractères «Mode (s) utilisateur», suivis de la valeur du temps CPU passé en mode utilisateur, signifiée par le %U
.
Nous utilisons n
pour donner une autre nouvelle ligne. Cette fois, nous nous préparons à la valeur temporelle du noyau. Nous imprimons les caractères «Kernel Mode (s)», suivis du spécificateur de format pour le temps CPU passé en mode noyau, qui est %S
.
Enfin, nous allons imprimer les caractères « n
CPU: ”pour nous donner une nouvelle ligne et le titre de cette valeur de données. Le %P
le spécificateur de format donnera le pourcentage moyen de temps CPU utilisé par le processus chronométré.
La chaîne de format entière est placée entre guillemets. Nous aurions pu inclure quelques t
caractères pour placer des tabulations dans la sortie si nous étions pointilleux sur l’alignement des valeurs.
time -f "Program: %CnTotal time: %EnUser Mode (s) %UnKernel Mode (s) %SnCPU: %P" ./loop1
Envoi de la sortie vers un fichier
Pour conserver un enregistrement des horaires des tests que vous avez effectués, vous pouvez envoyer la sortie de time
dans un fichier. Pour ce faire, utilisez le -o
(sortie) option. La sortie de votre programme sera toujours affichée dans la fenêtre du terminal. Ce n’est que la sortie de time
qui est redirigé vers le fichier.
Nous pouvons relancer le test et enregistrer la sortie dans le test_results.txt
fichier comme suit:
time -o test_results.txt -f "Program: %CnTotal time: %EnUser Mode (s) %UnKernel Mode (s) %SnCPU: %P" ./loop1
cat test_results.txt
Le loop1
la sortie du programme est affichée dans la fenêtre du terminal et les résultats de time
aller au test_results.txt
déposer.
Si vous souhaitez capturer le prochain ensemble de résultats dans le même fichier, vous devez utiliser le -a
(ajouter) comme suit:
time -o test_results.txt -a -f "Program: %CnTotal time: %EnUser Mode (s) %UnKernel Mode (s) %SnCPU: %P" ./loop2
cat test_results.txt
Il devrait maintenant être clair pourquoi nous avons utilisé le %C
spécificateur de format pour inclure le nom du programme dans la sortie de la chaîne de format.
Et nous sommes à court de temps
Probablement le plus utile aux programmeurs et aux développeurs pour affiner leur code, le time
La commande est également utile pour quiconque souhaite en savoir un peu plus sur ce qui se passe sous le capot à chaque fois que vous lancez un programme.