Como usar o comando time no Linux

PC Linux com uma janela de terminal aberta
Fatmawati Achmad Zaenuri / Shutterstock.com

Quer saber por quanto tempo um processo é executado e muito mais? O timecomando Linux retorna estatísticas de tempo, dando a você uma visão interessante sobre os recursos usados ​​por seus programas.

tempo tem muitos parentes

Existem muitas distribuições de Linux e diferentes sistemas operacionais do tipo Unix. Cada um deles possui um shell de comando padrão. O shell padrão mais comum nas distribuições Linux modernas é o shell bash. Mas existem muitos outros, como o shell Z (zsh) e o shell Korn (ksh).

Todas estas conchas incorporar seu próprio timecomando, como um built-in  comando ou como uma palavra reservada . Quando você digita timeem uma janela de terminal, o shell executa seu comando interno em vez de usar o timebinário GNU que é fornecido como parte de sua distribuição Linux.

Queremos usar a versão GNU do timeporque tem mais opções e é mais flexível.

Que horas vai ser executado?

Você pode verificar qual versão será executada usando o typecomando. typepermitirá que você saiba se o próprio shell irá lidar com sua instrução, com suas rotinas internas, ou passá-la para o binário GNU.

em uma janela de terminal, digite a palavra type, um espaço e, em seguida, a palavra timee pressione Enter.

digite tempo

digite o tempo em uma janela de terminal bash

Podemos ver que no shell bash timeé uma palavra reservada. Isso significa que o Bash usará suas timerotinas internas por padrão.

digite tempo

digite tempo em uma janela de terminal zsh

No shell Z (zsh) timeé uma palavra reservada, então as rotinas internas do shell serão usadas por padrão.

digite tempo

digite a hora em uma janela de shell Korn

No shell Korn, timeexiste uma palavra-chave. Uma rotina interna será usada em vez do time comando GNU .

Executando o comando GNU time

Se o shell em seu sistema Linux tiver uma timerotina interna, você precisará ser explícito se quiser usar o timebinário GNU . Você deve:

  • Fornece o caminho completo para o binário, como  /usr/bin/time. Execute o which timecomando para encontrar este caminho.
  • Use command time.
  • Use uma barra invertida como \time.

saída do comando de tempo em uma janela de terminal

O which timecomando nos fornece o caminho para o binário.

Podemos testar isso usando /usr/bin/time um comando para iniciar o binário GNU. Isso funciona. Recebemos uma resposta do timecomando informando que não fornecemos nenhum parâmetro de linha de comando para que ele funcione.

Recomendado:  Como usar um assistente de voz sem ele "Sempre ouvindo"

A digitação command timetambém funciona e obtemos as mesmas informações de uso de time. O commandcomando diz ao shell para ignorar o próximo comando para que seja processado fora do shell.

Usar um \caractere antes do nome do comando é o mesmo que usar commandantes do nome do comando.

A maneira mais simples de garantir que você está usando o timebinário GNU é usar a opção de barra invertida.

Tempo
\Tempo

tempo e \ saída de tempo em uma janela de terminal

timeinvoca a versão shell do tempo. \timeusa o  time binário .

Usando o comando de tempo

Vamos cronometrar alguns programas. Estamos usando dois programas chamados loop1e loop2. Eles foram criados a partir de loop1.ce loop2.c. Eles não fazem nada de útil além de demonstrar os efeitos de um tipo de ineficiência de codificação.

Este é o loop1.c. O comprimento de uma string é necessário dentro dos dois loops aninhados. O comprimento é obtido antecipadamente, fora dos dois loops aninhados.

#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";

 // obtém o comprimento da string uma vez, fora dos loops
 len = strlen (szString);  

 para (j = 0; j <500000; j ++) {

 para (i = 0; i <len; i ++) {

  if (szString [i] == '-')
    contagem ++;
   }
 }

 printf ("Contados% d hifens \ n", contagem);

 saída (0);

} // fim do principal

Este é o loop2.c. O comprimento da corda é obtido vez após vez para cada ciclo do loop externo. Essa ineficiência deve aparecer nos tempos.

#include "stdio.h"
#include "string.h"
#include "stdlib.h"

int main (int argc, char * argv [])
{
 int i, j, contagem = 0;
 char szString [] = "how-to-geek-how-to-geek-how-to-geek-how-to-geek-how-to-geek-how-to-geek";

 para (j = 0; j <500000; j ++) {

 // obtendo o comprimento da string a cada
 // tempo os loops disparam
 para (i = 0; i <strlen (szString); i ++) {

   if (szString [i] == '-')
    contagem ++;
   }
 }

 printf ("Contados% d hifens \ n", contagem);

 saída (0);

} // fim do principal

Vamos iniciar o loop1programa e usá-lo timepara medir seu desempenho.

\ time ./loop1

resultados de tempo para loop1 em uma janela de terminal

Agora vamos fazer o mesmo para loop2.

\ time ./loop2

saída de tempo para loop2 em uma janela de terminal

Isso nos deu dois conjuntos de resultados, mas eles estão em um formato muito feio. Podemos fazer algo sobre isso mais tarde, mas vamos escolher algumas informações dos resultados.

Recomendado:  O que é o Xbox Game Pass e vale a pena?

Quando os programas são executados, há dois modos de execução entre os quais eles são alternados. Eles são chamados de modo de usuário e modo de kernel .

Resumidamente, um processo no modo de usuário não pode acessar diretamente o hardware ou a memória de referência fora de sua própria alocação. Para obter acesso a tais recursos, o processo deve fazer solicitações ao kernel. Se o kernel aprovar a solicitação, o processo entra em execução no modo kernel até que o requisito seja satisfeito. O processo é então alternado de volta para execução no modo de usuário.

Os resultados para loop1nos loop1 mostram que gastou 0,09 segundos no modo de usuário. Ele gastou tempo zero no modo kernel ou o tempo no modo kernel é um valor muito baixo para registrar depois de arredondado para baixo. O tempo total decorrido foi de 0,1 segundos. loop1obteve uma média de 89% do tempo de CPU sobre a duração de seu tempo total decorrido.

O loop2programa ineficiente demorou três vezes mais para ser executado. Seu tempo total decorrido é de 0,3 segundos. A duração do tempo de processamento no modo de usuário é de 0,29 segundos. Nada está se registrando no modo kernel. loop2 obteve uma média de 96% do tempo de CPU para a duração de sua execução.

Formatando a saída

Você pode personalizar a saída timeusando uma string de formato. A string de formato pode conter especificadores de texto e formato. A lista de especificadores de formato pode ser encontrada na página de manual de time. Cada um dos especificadores de formato representa uma informação.

Quando a string é impressa, os especificadores de formato são substituídos pelos valores reais que representam. Por exemplo, o especificador de formato para a porcentagem de CPU é a letra P. Para indicar timeque um especificador de formato não é apenas uma letra regular, adicione um sinal de porcentagem a ela, como %P. Vamos usá-lo em um exemplo.

A opção -f(string de formato) é usada para dizer timeque o que se segue é uma string de formato.

Nossa string de formato irá imprimir os caracteres “Programa:” e o nome do programa (e quaisquer parâmetros de linha de comando que você passar para o programa). O %Cespecificador de formato significa “Nome e argumentos de linha de comando do comando sendo cronometrado”. O \nfaz com que a saída mova para a próxima linha.

Recomendado:  Como afinar sua guitarra com o Amazon Echo

Existem muitos especificadores de formato e eles diferenciam maiúsculas de minúsculas, portanto, certifique-se de inseri-los corretamente ao fazer isso.

A seguir imprimiremos os caracteres “Tempo total:” seguidos do valor do tempo total decorrido para esta execução do programa (representado por %E).

Costumamos \ndar outra nova linha. Em seguida, imprimiremos os caracteres “Modo (s) de usuário“, seguidos do valor do tempo de CPU gasto no modo de usuário, representado pelo %U.

Costumamos \ndar outra nova linha. Desta vez, estamos nos preparando para o valor de tempo do kernel. Imprimimos os caracteres “Kernel Mode (s)“, seguidos do especificador de formato para o tempo de CPU gasto no modo kernel, que é %S.

Finalmente, vamos imprimir os caracteres “ \nCPU:” para nos dar uma nova linha e o título para este valor de dados. O %P especificador de formato fornecerá a porcentagem média de tempo de CPU usado pelo processo cronometrado.

Toda a string de formato é colocada entre aspas. Poderíamos ter incluído alguns \tcaracteres para colocar tabulações na saída se estivéssemos preocupados com o alinhamento dos valores.

\ time -f "Programa:% C \ nTempo total:% E \ nModo (s) do usuário% U \ nModo (s) do kernel% S \ nCPU:% P" ./loop1

Saída da string de formato para loop1 em uma janela de terminal

Enviando a saída para um arquivo

Para manter um registro das temporizações dos testes realizados, você pode enviar a saída de timepara um arquivo. Para fazer isso, use a -oopção (saída). A saída do seu programa ainda será exibida na janela do terminal. É apenas a saída timeque é redirecionada para o arquivo.

Podemos executar novamente o teste e salvar a saída no test_results.txtarquivo da seguinte maneira:

\ time -o test_results.txt -f "Programa:% C \ nTempo total:% E \ nModo (s) de usuário% U \ nModo (s) kernel% S \ nCPU:% P" ./loop1
cat test_results.txt

Saída da string de formato para loop1 canalizada para o arquivo em uma janela de terminal

A loop1saída do programa é exibida na janela do terminal e os resultados timevão para o test_results.txtarquivo.

Se você deseja capturar o próximo conjunto de resultados no mesmo arquivo, deve usar a -aopção (anexar) da seguinte forma:

\ time -o test_results.txt -a -f "Programa:% C \ nTempo total:% E \ nModo (s) do usuário% U \ nModo (s) kernel% S \ nCPU:% P" ./loop2
cat test_results.txt

Saída da string de formato para loop2 anexada ao arquivo em uma janela de terminal

Agora deve estar claro por que usamos o %Cespecificador de formato para incluir o nome do programa na saída da string de formato.

E estamos sem tempo

Provavelmente mais útil para programadores e desenvolvedores para ajustar seu código, o timecomando também é útil para quem deseja descobrir um pouco mais sobre o que acontece nos bastidores cada vez que você inicia um programa.