[SP-pm] Chamar muitas vezes o system()

breno breno at rio.pm.org
Tue Feb 17 07:10:23 PST 2015


2015-02-16 15:47 GMT-02:00 Nilton OS <jniltinho at gmail.com>:

> Olá a todos, boa tarde, gostaria de tirar uma dúvida, chamar o system()
> muitas vezes um em script em perl eu tenho perda de performance.
>
>
Oi Nilton,

como o Renato bem citou, system() faz fork no seu processo, e muitas
chamadas podem potencialmente causar algum impacto no desempenho. Mas...
tem certeza que isso é um problema do system() e não do que está sendo
executado *pelo* system()? Ou algo completamente diferente?

Lembre-se que correlação não implica causalidade. Você deve ter observado
que, ao adicionar mais chamadas ao system(), seu script ficou mais lento.
Mas cada chamada ao system() *executa* um programa externo, programa esse
que também leva tempo pra executar e retornar. Será que não é um desses
carinhas que está impactando o desempenho? Um novo filtro que você ativou,
talvez? Ou de repente algum outro ponto do código está com problemas e ter
colocado as chamadas extras ao system() só evidenciou isso? Por exemplo, a
lógica de operar com os filtros pode gastar tempo de forma exponencial em
vez de linear ou constante, ou seja, o script opera rápido para 100 emails
por segundo, mas degrada horrivelmente pra 1000 emails.

Estou surpreso que não te sugeriram analisar o código com Devel::NYTProf
para tentar encontrar os verdadeiros gargalos do script. Após instalar o
módulo, basta rodar o script como:

    perl -d:NYTProf meu_programa_lento.pl

Isso vai criar o arquivo "nytprof.out". Você converte e visualiza ele em
html digitando:


nytprofhtml --open


A documentação completa vc encontra em
https://metacpan.org/pod/Devel::NYTProf

Se de fato o gargalo de execução estiver no system() e se de fato forem só
operações de "mv" e "rm", isso pode evidenciar um problema no seu sistema
de arquivos. Falando nisso, qual é o seu sistema de arquivos? Operações de
remover diretórios inteiros no ext4 são conhecidamente lentas porque é
preciso varrer a estrutura inteira e fazer syscalls de "unlink" e "rmdir"
em cada um deles. Dependendo da organização dos subdiretórios e da
quantidade de arquivos, uma chamada ao "rm -r" pode levar semanas em vez de
horas ou minutos. A velocidade de uma operação dessas com muitos arquivos a
serem removidos vai depender também dos IOPS do seu volume. Aí o pessoal de
hardware da lista vai poder te ajudar muito mais do que eu.

Você pode melhorar o desempenho fazendo alguns truques, que podem variar de
atualizar o seu GNU coreutils (se o sistema é muito antigo e nunca foi
atualizado, pode estar usando um "rm" velho que apaga estruturas em O(n^2)
no ext3/ext4 em vez de desempenho linear), desativar o journaling (não
recomendado!), usar um sistema que arquivos mais eficiente para remoção
(ouvi falar coisas boas sobre o btrfs), um que apague apenas a referência
em vez de sobrescrever o bloco/extent inteiro, paralelizar o "rm" usando
xargs, fazer a remoção usando outro processo assincrono ao seu script de
filtros, etc.

O mesmo vale para operações de "mv". Se estiver usando sistemas de arquivos
ou dispositivos diferentes entre o diretório de origem e de destino, por
exemplo, um mv deixa de ser uma operação imediata que sequer acessa os
dados e vira uma operação de cópia recursiva lenta que doi (
http://en.wikipedia.org/wiki/Mv#Moving_versus_copying_and_removing).

Boa sorte!

[]s

-b
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.pm.org/pipermail/saopaulo-pm/attachments/20150217/d116a71c/attachment.html>


More information about the SaoPaulo-pm mailing list