Come utilizzare il comando time su Linux

Vuoi sapere quanto dura un processo e molto altro ancora? Il comando time di Linux restituisce le statistiche temporali, fornendoti interessanti informazioni sulle risorse utilizzate dai tuoi programmi.

il tempo ha molti parenti

Esistono molte distribuzioni Linux e diversi sistemi operativi simili a Unix. Ognuno di questi ha una shell dei comandi predefinita. La shell predefinita più comune nelle moderne distribuzioni Linux è la shell bash. Ma ce ne sono molte altre, come la shell Z (zsh) e la shell Korn (ksh).

Tutte queste shell incorporano il proprio comando temporale, sia come file incorporato comando o come file parola riservata. Quando digiti time in una finestra di terminale, la shell eseguirà il suo comando interno invece di usare il binario temporale GNU fornito come parte della tua distribuzione Linux.

Vogliamo usare la versione GNU del tempo perché ne ha di più opzioni ed è più flessibile.

A che ora verrà eseguito?

È possibile verificare quale versione verrà eseguita utilizzando il comando type. type ti farà sapere se la shell gestirà la tua istruzione da sola, con le sue routine interne, o la passerà al binario GNU.

in una finestra di terminale digita il tipo di parola, uno spazio, quindi la parola ora e premi Invio.

type time

Possiamo vedere che nella shell bash il tempo è una parola riservata. Ciò significa che Bash userà le sue routine internaltime per impostazione predefinita.

type time

digitare time in una finestra del terminale zsh

Nella shell Z (zsh) il tempo è una parola riservata, quindi le routine della shell interna verranno utilizzate per impostazione predefinita.

type time

digitare l'ora in una finestra della shell Korn

Nella shell Korn il tempo è una parola chiave. Verrà utilizzata una routine interna al posto del comando GNU time.

Esecuzione del comando GNU time

Se la shell sul tuo sistema Linux ha una routine temporale interna, dovrai essere esplicito se desideri utilizzare il binario temporale GNU. Devi:

Fornisci l’intero percorso del file binario, come / usr / bin / time. Eseguire il comando which time per trovare questo percorso.
Usa il tempo di comando.
Usa una barra rovesciata come il tempo.

output del comando time in una finestra di terminale

Il comando which time ci fornisce il percorso per il binario.

Possiamo testarlo usando / usr / bin / time come comando per avviare il binario GNU. Che funzioni. Riceviamo una risposta dal comando time che ci informa che non abbiamo fornito alcun parametro della riga di comando per il suo funzionamento.

Anche la digitazione dell’ora del comando funziona e otteniamo le stesse informazioni sull’utilizzo da tempo. Il comando command dice alla shell di ignorare il comando successivo in modo che venga elaborato al di fuori della shell.

Usare un carattere prima del nome del comando equivale a usare il comando prima del nome del comando.

Il modo più semplice per assicurarti di utilizzare il binario temporale GNU è usare l’opzione barra rovesciata.

time
time

ora e ora in una finestra di terminale

time richiama la versione shell di time. time utilizza l’ora binaria.

Utilizzando il comando time

Cronometriamo alcuni programmi. Stiamo usando due programmi chiamati loop1 e loop2. Sono stati creati da loop1.c e loop2.c. Non fanno nulla di utile oltre a dimostrare gli effetti di un tipo di inefficienza di codifica.

Questo è loop1.c. La lunghezza di una stringa è richiesta all’interno dei due cicli annidati. La lunghezza è ottenuta in anticipo, al di fuori dei due loop annidati.

#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

This is loop2.c. The length of the string is obtained time after time for every cycle of the outer loop. This inefficiency ought to show up in the timings.

#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

Let’s fire up the loop1 program and use time to measure its performance.

time ./loop1

risultati di tempo per loop1 in una finestra di terminale

Ora facciamo lo stesso per loop2.

time ./loop2

uscita temporale per loop2 in una finestra di terminale

Questo ci ha dato due serie di risultati, ma sono in un formato davvero brutto. Possiamo fare qualcosa in seguito, ma selezioniamo alcune informazioni dai risultati.

Quando i programmi vengono eseguiti, ci sono due modalità di esecuzione tra le quali vengono commutate avanti e indietro. Questi sono chiamati modalità utente e modalità kernel.

In breve, un processo in modalità utente non può accedere direttamente all'hardware o alla memoria di riferimento al di fuori della propria allocazione. Per avere accesso a tali risorse, il processo deve effettuare richieste al kernel. Se il kernel approva la richiesta, il processo entra in esecuzione in modalità kernel fino a quando il requisito non è stato soddisfatto. Il processo viene quindi riportato all'esecuzione in modalità utente.

I risultati per loop1 ci dicono che loop1 ha trascorso 0,09 secondi in modalità utente. O ha trascorso zero tempo in modalità kernel o il tempo in modalità kernel è un valore troppo basso per essere registrato una volta che è stato arrotondato per difetto. Il tempo trascorso totale è stato di 0,1 secondi. a loop1 è stata assegnata una media dell'89% del tempo di CPU per la durata del tempo totale trascorso.

Il programma inefficiente loop2 ha richiesto tre volte più tempo per essere eseguito. Il suo tempo totale trascorso è di 0,3 secondi. La durata del tempo di elaborazione in modalità utente è di 0,29 secondi. Niente si sta registrando per la modalità kernel. a loop2 è stata assegnata una media del 96% del tempo di CPU per la durata della sua esecuzione.

Formattazione dell'output

È possibile personalizzare l'output dal tempo utilizzando una stringa di formato. La stringa di formato può contenere testo e specificatori di formato. L'elenco degli identificatori di formato può essere si trova nella pagina man per tempo. Ciascuno degli identificatori di formato rappresenta un'informazione.

Quando la stringa viene stampata, gli identificatori di formato vengono sostituiti dai valori effettivi che rappresentano. Ad esempio, l'identificatore di formato per la percentuale di CPU è la lettera P. Per indicare al tempo che un identificatore di formato non è solo una lettera normale, aggiungi un segno di percentuale, come% P. Usiamolo in un esempio.

L'opzione -f (stringa di formato) viene utilizzata per indicare al tempo che ciò che segue è una stringa di formato.

La nostra stringa di formato stamperà i caratteri "Programma:" e il nome del programma (e tutti i parametri della riga di comando che passate al programma). L'identificatore di formato% C sta per "Nome e argomenti della riga di comando del comando da cronometrare". La n fa sì che l'output si sposti alla riga successiva.

Ci sono molti specificatori di formato e fanno distinzione tra maiuscole e minuscole, quindi assicurati di inserirli correttamente quando lo fai per te stesso.

Successivamente, stamperemo i caratteri "Tempo totale:" seguito dal valore del tempo totale trascorso per questa esecuzione del programma (rappresentato da% E).

Usiamo n per dare un'altra nuova linea. Stamperemo quindi i caratteri "Modalità utente", seguiti dal valore del tempo della CPU trascorso in modalità utente, indicato da% U.

Usiamo n per dare un'altra nuova linea. Questa volta ci stiamo preparando per il valore temporale del kernel. Stampiamo i caratteri "Kernel Mode (s)", seguiti dall'identificatore di formato per il tempo della CPU trascorso in modalità kernel, che è% S.

Infine, stamperemo i caratteri "nCPU:" per darci una nuova riga e il titolo per questo valore di dati. L'identificatore di formato% P fornirà la percentuale media di tempo della CPU utilizzata dal processo a tempo.

L'intera stringa di formato è racchiusa tra virgolette. Avremmo potuto includere alcuni caratteri t per posizionare le tabulazioni nell'output se fossimo stati pignoli sull'allineamento dei valori.

time -f "Program: %CnTotal time: %EnUser Mode (s) %UnKernel Mode (s) %SnCPU: %P" ./loop1

Output dalla stringa di formato per loop1 in una finestra di terminale

Invio dell'output a un file

Per tenere traccia delle tempistiche dei test che hai condotto puoi inviare l'output di volta in volta a un file. Per fare questo usa l'opzione -o (output). L'output del programma verrà comunque visualizzato nella finestra del terminale. È solo l'output di time che viene reindirizzato al file.

Possiamo rieseguire il test e salvare l'output nel file test_results.txt come segue:

time -o test_results.txt -f "Program: %CnTotal time: %EnUser Mode (s) %UnKernel Mode (s) %SnCPU: %P" ./loop1
cat test_results.txt

Output dalla stringa di formato per loop1 reindirizzato al file in una finestra di terminale

L'output del programma loop1 viene visualizzato nella finestra del terminale e i risultati di tempo vanno al file test_results.txt.

Se desideri acquisire la serie successiva di risultati nello stesso file, devi utilizzare l'opzione -a (append) come segue:

time -o test_results.txt -a -f "Program: %CnTotal time: %EnUser Mode (s) %UnKernel Mode (s) %SnCPU: %P" ./loop2
cat test_results.txt

Output dalla stringa di formato per loop2 aggiunta al file in una finestra di terminale

Ora dovrebbe essere evidente il motivo per cui abbiamo utilizzato l'identificatore di formato% C per includere il nome del programma nell'output dalla stringa di formato.

E siamo fuori tempo

Probabilmente di grande utilità a programmatori e sviluppatori per mettere a punto il loro codice, il comando time è utile anche per chiunque voglia scoprire qualcosa in più su ciò che accade sotto il cofano ogni volta che si avvia un programma.