Haverá tipicamente (falta de truque de cópia zero ) uma sobrecarga mensurável devido ao IPC extra: copiar o dados de um processo para outro, em vez do processo "workhorse" ler arquivos diretamente. Um pipe também pode resultar em perda de desempenho (ou funcionalidade) para outros motivos : com entrada canalizada, um processo não pode seek()
em sua entrada e não pode mmap()
it.
Geralmente, os principais gargalos de desempenho são provavelmente E / S de disco e tempo de computação da CPU (que, presumivelmente, é intensivo no seu caso). Estes podem ser muito maiores do que o overhead do IPC, mas há muitas variáveis aqui (tipo de CPU, tipo de disco e tipo de sistema de arquivos, RAM física disponível, SO e versão, libc e versão - pelo menos).
Você pode ter uma idéia aproximada do desempenho com alguns testes rápidos, tomando o cuidado de liberar o cache de disco antes de cada um (estou usando o linux, eu uso este método ) entre cada teste.
# time ( pv -pt somethinglarge.iso | sha256sum )
[...]
real 0m8.066s
user 0m5.146s
sys 0m1.075s
# time ( sha256sum somethinglarge.iso )
[...]
real 0m7.913s
user 0m5.064s
sys 0m0.309s
Observe o real e o usuário e os tempos semelhantes e o aumento marcado no tempo do sistema para o caso canalizado devido à cópia extra.
Em alguns sistemas operacionais, especificamente o Linux, você poderá ler estatísticas de E / S por processo de /proc
(consulte 3.3) (você precisará de CONFIG_TASKSTATS
ativado no kernel para isso). Isso não é tão fácil ou tão simples quanto pv
, mas é baixo demais. pidstat
usa isso, ele pode ser usado para mostrar a taxa de transferência em tempo real (taxa) em um PID, mas é menos útil como um indicador de conclusão.
Uma opção linux similar (esta não precisa de CONFIG_TASKSTATS
), dado um descritor de processo e arquivo, você pode rastrear o deslocamento do descritor de arquivo em /proc/PID/fdinfo/FD
(o campo pos:
). Aqui está um script de brinquedo que mostra isso:
FILE=/tmp/some-large-input
SZ=$(stat -c "%s" "$FILE")
# start slow process in background
( some-slow-command $FILE ) &
PID=$!
FD=/proc/$PID/fdinfo/3 # some experimentation required
# or iterate over /proc/$PID/fd/* with readlink
# start %-ometer in background, exits when FD disappears
(
while nawk '/^pos:/{printf("%i\n",$2*100/'$SZ')}' $FD 2>/dev/null ; do
sleep 5 # adjust
done | dialog --gauge "$PID: processing $FILE ($SZ bytes)" 10 60
) &
wait $PID
if [ $? -eq 0 ]; then
echo 100 | dialog --gauge "$PID: completed $FILE ($SZ bytes)" 10 60
else
echo ...
fi
(Advertência: não precisa para arquivos pequenos, o buffer libc stdio distorcerá os resultados.)
Outras opções que me ocorrem agora:
-
use
lsof
para monitorar um processo de offsets fd não é exatamente leve, mas multiplataforma, e você pode iniciá-lo em qualquer processo de execução longa após o fato, o que não é possível compv
(também não é bonito, poislsof
se recusa a fornecer o tamanho e o deslocamento de uma só vez) -
algo hackish com
LD_PRELOAD
e alguns stubs que rastreiam dados de leitura / gravação, isso também é multi-plataforma, mas eu acho que você teria que escrever o seu próprio (eu não conheço nenhum que faça exatamente isso isso, mas aqui está uma resposta relacionada minha -
Atualização: alguém se deu ao trabalho de escrever uma ferramenta de monitoramento de transferência de propósito geral cv para uso com comandos coreutils no Linux. Ele usa uma lógica semelhante à abordagem
/proc
fdinfo
(conforme demonstrado no hack de shell acima). Ele também possui um modo de segundo plano no qual ele verifica / proc e relata as transferências em andamento conforme as encontra. Veja a questão relacionada É possível ver a velocidade do CP e a porcentagem copiado?