Para comparar tempos de execução de scripts de entre diferentes conchas, algumas respostas SE sugerir o uso bash
de alto- time
comando, assim:
time bash -c 'foo.sh'
time dash -c 'foo.sh'
... etc , para cada shell testar. Esses benchmarks falham em eliminar o tempo necessário para cada shell carregar e inicializar a si próprio . Por exemplo, suponha que ambos os comandos acima foram armazenados em um dispositivo lento com a velocidade de leitura de um disquete inicial (124KB / s), dash
(um executável de ~ 150K ) carregaria cerca de 7x mais rápido que bash
( ~ 1M ), o shell o tempo de carregamento distorceria os time
números - os tempos de pré-carregamento dessas conchas eram irrelevantes para medir os tempos de execução foo.sh
sob cada concha após o carregamento das conchas.
Qual é a melhor util portátil e geral para correr para o sincronismo script que pode ser executado a partir de dentro de cada shell? Portanto, o código acima seria algo como:
bash -c 'general_timer_util foo.sh'
dash -c 'general_timer_util foo.sh'
NB: no shell built-in time
comandos, uma vez que nenhum são portáteis ou geral.
Melhor ainda, se o utilitário também puder avaliar o tempo gasto pelos comandos e pipelines internos de um shell, sem que o usuário precise primeiro envolvê-los em um script. Sintaxe artificial como esta ajudaria:
general_timer_util "while read x ; do echo x ; done < foo"
Algumas conchas time
podem gerenciar isso. Por exemplo bash -c "time while false ; do : ; done"
funciona. Para ver o que funciona (e não funciona) no seu sistema, tente:
tail +2 /etc/shells |
while read s ; do
echo $s ; $s -c "time while false ; do : ; done" ; echo ----
done
/usr/bin/time
?Respostas:
Você deve observar que
time
é especificado pelo POSIX e AFAICT, a única opção mencionada pelo POSIX (-p
) é suportada corretamente por vários shells:fonte
time
. É comparável a deixar os velocistas medirem seu próprio tempo em 100m, individualmente, em vez de fazê-lo com um relógio ao mesmo tempo. Esta é, obviamente, picuinhas, mas ainda assim ...time
não era portátil; parece ser portátil. (Eu concordo com o seu ponto sobre a comparabilidade, embora)dash -c 'time -p while false ; do : ; done'
retorna "time: não pode ser executado enquanto: Não existe nenhum arquivo ou diretório <cr> Comando encerrado com erros de status diferente de zero 127" .Eu uso o comando GNU
date
, que suporta um timer de alta resolução:E então eu chamo o script assim:
A unidade de saída está em milissegundos.
fonte
date
especificamente.START
eEND
está definido; isso obviamente afetaria seu resultado. Não faço ideia do quão preciso você precisa e se importa no seu caso, mas como eu disse, algo para se ter em mente. (História engraçada: Eu conheço um software onde exatamente ele levou a um resultado inesperadamente negativos - foi usado para rendimento cálculos - que, em seguida, quebrou algumas coisas.)O
time
utilitário geralmente é incorporado ao shell, como você notou, o que o torna inútil como um temporizador "neutro".No entanto, o utilitário geralmente também está disponível como um utilitário externo
/usr/bin/time
, que pode muito bem ser usado para executar as experiências de tempo que você propõe.fonte
foo.sh
é executável e tem um shebang, isso sempre o executa com o mesmo shell e conta o tempo de inicialização desse shell, portanto, não é isso que o OP deseja. Sefoo.sh
estiver faltando um desses, isso não funcionará.time
" em consideração, parece. O tempo de inicialização do shell pode precisar ser medido separadamente.time
comando interno. No entanto, muitas conchas, incluindobash
umatime
palavra - chave, podem ser usadas para cronometrar pipelines. Para desativar essa palavra-chave para que otime
comando (no sistema de arquivos) seja usado, você pode citá-la como"time" foo.sh
. Veja também unix.stackexchange.com/search?q=user%3A22565+time+keywordAqui está uma solução que:
Há duas partes: um pequeno programa C que termina
gettimeofday
, que é preterido, mas ainda mais portátil que umclock_gettime
, e um pequeno script de shell que usa esse programa para obter um relógio de microssegundo lendo os dois lados da fonte de um script. O programa C é a única maneira portátil e com sobrecarga mínima para obter uma precisão de menos de um segundo em um registro de data e hora.Aqui está o programa C
epoch.c
:E o script de shell
timer
:Este é o padrão linguagem de comandos shell e
bc
e deve funcionar como um script em qualquer shell compatível com POSIX.Você pode usar isso como:
Ele não mede o tempo do sistema ou do usuário, apenas o tempo decorrido do relógio de parede não monotônico. Se o relógio do sistema mudar durante a execução do script, isso fornecerá resultados incorretos. Se o sistema estiver sob carga, o resultado não será confiável. Eu não acho que nada melhor possa ser portátil entre conchas.
Um script de timer modificado pode ser usado
eval
para executar comandos fora de um script.fonte
eval
), eu estava ajustando o script na resposta de Rabin para incluireval "$@"
, para que ele pudesse executar os shell shell rapidamente .Solução revisada várias vezes usando
/proc/uptime
edc
/bc
/awk
em grandes partes, graças à entrada da agc :Supõe obviamente que
/proc/uptime
existe e tem uma determinada forma.fonte
/proc
sistema de arquivos. Se isso é uma preocupação ou não, eu não sei.awk
pode ser significativa. Talvezb=$(cat /proc/uptime)
antes, em seguida,a=$(cat /proc/uptime)
depois de, em seguida, analisar $ a e $ b e subtrair.read
são melhores do quecat
, isso seria mais limpa (e um pouco mais rápido):read before dummyvar < /proc/uptime ;sleep 2s;read after dummyvar < /proc/uptime; duration=$(dc -e "${after} ${before} - n");echo "It took $duration seconds."