Hur man använder tidskommandot på Linux

Vill du veta hur länge en process pågår och mycket mer? Linux-tidskommandot returnerar tidsstatistik, vilket ger dig coola insikter om resurserna som används av dina program.

tiden har många släktingar

Det finns många Linux-distributioner och olika Unix-liknande operativsystem. Var och en av dessa har ett standardkommandoskal. Det vanligaste standardskalet i moderna Linux-distributioner är bash-skalet. Men det finns många andra, som Z-skalet (zsh) och Korn-skalet (ksh).

Alla dessa skal innehåller sitt eget tidskommando, antingen som en inbyggt kommando eller som en reserverat ord. När du skriver tid i ett terminalfönster kommer skalet att köra sitt interna kommando istället för att använda GNU-tidsbinären som tillhandahålls som en del av din Linux-distribution.

Vi vill använda GNU-versionen av tid eftersom den har mer alternativ och är mer flexibel.

Vilken tid kommer springa?

Du kan kontrollera vilken version som körs genom att använda typkommandot. typ låter dig veta om skalet kommer att hantera din instruktion själv, med dess interna rutiner, eller skicka den vidare till GNU-binären.

i ett terminalfönster skriv in ordtypen, ett mellanslag och sedan ordet tid och tryck på Enter.

type time

Vi kan se att i bash-skalet är tid ett reserverat ord. Detta innebär att Bash kommer att använda sina interna tidsrutiner som standard.

type time

I Z-skalet (zsh) är tiden ett reserverat ord, så de interna skalrutinerna kommer att användas som standard.

type time

I Korn-skalet är tid ett nyckelord. En intern rutin kommer att användas istället för GNU-tidskommandot.

Kör GNU-tidskommandot

Om skalet på ditt Linux-system har en intern tidsrutin måste du vara tydlig om du vill använda GNU-tidsbinären. Du måste antingen:

Ange hela sökvägen till binären, såsom /usr/bin/time. Kör kommandot which time för att hitta den här sökvägen.
Använd kommandotid.
Använd ett snedstreck som tid.

Kommandot which time ger oss vägen till binären.

Vi kan testa detta genom att använda /usr/bin/time som ett kommando för att starta GNU-binären. Det fungerar. Vi får ett svar från tidskommandot som talar om för oss att vi inte angav några kommandoradsparametrar för det att fungera på.

Att skriva kommandotid fungerar också, och vi får samma användningsinformation från tiden. Kommandokommandot säger åt skalet att ignorera nästa kommando så att det bearbetas utanför skalet.

Att använda ett tecken före kommandonamnet är detsamma som att använda kommandot före kommandonamnet.

Det enklaste sättet att säkerställa att du använder GNU time binär är att använda backslash alternativet.

time
time

tid åberopar skalversionen av tid. tid använder tiden binär.

Använda tidskommandot

Låt oss tajma några program. Vi använder två program som heter loop1 och loop2. De skapades från loop1.c och loop2.c. De gör inget användbart förutom att demonstrera effekterna av en typ av kodningsineffektivitet.

Detta är loop1.c. Längden på en sträng krävs inom de två kapslade slingorna. Längden erhålls i förväg, utanför de två kapslade slingorna.

#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

Låt oss nu göra samma sak för loop2.

time ./loop2

Det har gett oss två uppsättningar resultat, men de är i ett riktigt fult format. Vi kan göra något åt ​​det senare, men låt oss välja några informationsbitar från resultaten.

När program körs finns det två exekveringslägen som de växlas fram och tillbaka mellan. Dessa kallas användarläge och kärnläge.

Kort sagt, en process i användarläge kan inte direkt komma åt hårdvara eller referensminne utanför sin egen allokering. För att få tillgång till sådana resurser måste processen göra förfrågningar till kärnan. Om kärnan godkänner begäran går processen in i kärnlägesexekvering tills kravet har uppfyllts. Processen växlas sedan tillbaka till körning av användarläge.

Resultaten för loop1 berättar att loop1 spenderade 0,09 sekunder i användarläge. Den tillbringade antingen noll tid i kärnläge eller så är tiden i kärnläge för lågt för att registreras när den väl har avrundats nedåt. Den totala förflutna tiden var 0,1 sekunder. loop1 tilldelades i genomsnitt 89 % av CPU-tiden under den totala förflutna tiden.

Det ineffektiva loop2-programmet tog tre gånger längre tid att köra. Dess totala förflutna tid är 0,3 sekunder. Bearbetningstiden i användarläge är 0,29 sekunder. Ingenting registreras för kärnläge. loop2 tilldelades i genomsnitt 96 % av CPU-tiden under hela dess körning.

Formatera utdata

Du kan anpassa utdata från tid till annan med en formatsträng. Formatsträngen kan innehålla text och formatspecifikationer. Listan över formatspecifikationer kan vara finns på man-sidan för tid. Var och en av formatspecifikationerna representerar en del information.

När strängen skrivs ut ersätts formatspecifikationerna med de faktiska värden de representerar. Till exempel är formatspecifikationen för procentandelen CPU bokstaven P . För att visa att en formatspecifikator inte bara är en vanlig bokstav, lägg till ett procenttecken, som %P . Låt oss använda det som ett exempel.

Alternativet -f (formatsträng) används för att tala om för tiden att det som följer är en formatsträng.

Vår formatsträng kommer att skriva ut tecknen "Program:" och namnet på programmet (och alla kommandoradsparametrar som du skickar till programmet). %C-formatspecifikationen står för "Namn och kommandoradsargument för kommandot som tidsbestäms". n gör att utgången flyttas till nästa rad.

Det finns många formatspecifikationer och de är skiftlägeskänsliga, så se till att du anger dem korrekt när du gör detta för er själva.

Därefter kommer vi att skriva ut tecknen "Total tid: " följt av värdet på den totala förflutna tiden för denna körning av programmet (representeras av %E).

Vi använder n för att ge ytterligare en ny rad. Vi kommer sedan att skriva ut tecknen "Användarläge(n) ", följt av värdet på CPU-tiden i användarläge, betecknat med %U.

Vi använder n för att ge ytterligare en ny rad. Den här gången förbereder vi oss för kärnans tidsvärde. Vi skriver ut tecknen "Kernel Mode (s) ", följt av formatspecifikationen för CPU-tid som spenderas i kärnläge, vilket är %S.

Slutligen kommer vi att skriva ut tecknen "nCPU: " för att ge oss en ny rad och titeln för detta datavärde. %P-formatspecifikationen kommer att ge den genomsnittliga procentandelen av CPU-tid som används av den tidsinställda processen.

Hela formatsträngen är inslagen i citattecken. Vi kunde ha inkluderat några t tecken för att placera tabbar i utgången om vi var noga med justeringen av värdena.

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

Skickar utdata till en fil

För att hålla ett register över tiderna från de tester du har genomfört kan du skicka utdata då och då till en fil. Använd alternativet -o (utgång) för att göra detta. Utdata från ditt program kommer fortfarande att visas i terminalfönstret. Det är bara utdata från tiden som omdirigeras till filen.

Vi kan köra testet igen och spara utdata i filen test_results.txt enligt följande:

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

Programutgången loop1 visas i terminalfönstret och resultaten från tiden går till filen test_results.txt.

Om du vill fånga nästa uppsättning resultat i samma fil måste du använda alternativet -a (lägg till) enligt följande:

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

Det borde nu vara uppenbart varför vi använde %C-formatspecifikationen för att inkludera namnet på programmet i utdata från formatsträngen.

Och vi har inte tid

Förmodligen är det mest användbar för programmerare och utvecklare för att finjustera sin kod, tidskommandot är också användbart för alla som vill upptäcka lite mer om vad som händer under huven varje gång du startar ett program.