Enviado via iPad
Em 09/12/2012, às 04:48, breno <br...@rio.pm.org> escreveu: > 2012/12/9 Aureliano Guedes <guedes_1...@hotmail.com>: >> Breno, so uma duvida, antigamente eu usava muito arquivos temporario, eu >> deixei de usar pois achava que perdia muito em performance. >> >> Você acha que eu perco muito em performance usando a solução 4 no lugar das >> outras soluções? > > Resposta brevíssima: não importa. > > > > Pronto. Pode parar de ler aqui. É sério. Se, por alguma curiosidade > mórbida, vc quiser mais detalhes, continue lendo :) > Minha curiosidade não é mórbida. :) > > > Como a maioria das coisas do mundo, depende. Se você tiver RAM > infinita, manter tudo em memória é sempre muito mais rápido do que > fazer acessos ao disco. Para saber mais: > https://en.wikipedia.org/wiki/Space-time_tradeoff > > No entanto, há casos em que você *quer* armazenar dados em arquivos > temporários, não só por questões de memória, mas também para ter > estados intermediários em sua execução. Ou quando, como no exemplo > anterior, vc quer transformar um arquivo em outro. Afinal, pense > comigo: se vc vai ler um arquivo de entrada e escrever num arquivo de > saída, pq precisa que seja o mesmo arquivo? Preservar o arquivo > original pode te ajudar não só na simplicidade do código como nos > casos em que você quer validar os resultados repetindo a execução, ou > depurar seu programa caso algo estranho esteja acontecendo. Sem o > original intacto, como recuperá-lo? Você provavelmente está guardando > cópia do arquivo original em algum lugar (por esses mesmos motivos) > então pq não oficializar a coisa e gravar a saída processada em outro > arquivo (que portanto deixa de ser temporário)? > > Vejamos as operações envolvidas no problema. Sem arquivos temporário, > temos os seguintes passos: > > 1) ler o arquivo todo do disco para memória > 2) processar os dados > 3) voltar a posição do handle para o início do arquivo > 4) escrever o arquivo no disco > 5) truncar o restante > > Já com arquivos temporários, temos: > > 1) ler o arquivo do disco para memória > 2) processar os dados > 3) escrever o arquivo novo no disco > 4) renomear arquivo no disco para substituir original (se não for usar) > > Otimizações à parte, o processo em si é bastante parecido, com uma > ação de leitura e outra de escrita (ok, duas se rolar o rename, mas > não é lá uma grande operação de E/S), então não deve fazer lá grandes > diferenças em termos de desempenho. Antes de continuar, esqueci de > colocar na resposta anterior uma outra solução entre a 4 e a 5, vamos > chamá-la de 4.5: > > ----------8<----------- > #!/usr/bin/env perl > use strict; > use warnings; > use autodie; > > my $nome_original = 'arquivo.txt'; > > open my $orig_fh, '<', $nome_original; > > my @linhas; > my $i = 0; > while ( my $linha = <$orig_fh> ) { > if ($linha =~ s/^>.+$/>contig$i/ ) { > $i++; > } > } > continue { > push @linhas, $linha; > } > close $orig_fh; > > open $orig_fh, '>', $nome_original; > print $orig_fh @linhas; > close $orig_fh; > ---------->8----------- > > Essa solução tem duas diferenças em relação à 4. Aqui, estamos > acumulando os dados processados em memória (na variável @linhas) e, > após o processamento, reabrimos o mesmo arquivo, só que para escrita. > Continuamos com o perigo da manipulação sem locking, mas eliminamos a > necessidade do arquivo temporário. > > Particularmente, continuo preferindo a solução 4, pelos mesmos motivos de > antes. > > Uma nota sobre desempenho: quando o único fator a ser considerado é > desempenho, a melhor solução é escrever em Assembly. Mais ainda: > quando o único fator a ser considerado for desempenho, ou você está > desenvolvendo algo muito específico *mesmo* ou, em geral, há uma > chance muito grande de algo estar fundamentalmente errado no seu > raciocínio. Esse erro é conhecido como "otimização prematura". Nas > palavras de Donald Knuth: > > "Programadores desperdiçam um tempo enorme pensando sobre, ou se > preocupando com, a velocidade de partes não críticas de seus > programas, e essas tentativas de melhorar a eficiência na verdade > acabam tendo um forte impacto negativo quando depuração e manutenção > são consideradas. Precisamos esquecer eficiências menores em, digamos, > 97% do tempo: otimização prematura é a raiz de todo o mal. No entanto > não podemos deixar passar a oportunidade naqueles 3% crítico." > > Sempre que pensar em desempenho, lembre-se dessas sábias palavras. > > (Para saber mais sobre a questão: > http://c2.com/cgi/wiki?PrematureOptimization) > > Para o seu caso, isso significa: programe SEMPRE com foco em > legibilidade, testabilidade e manutenção. Preocupe-se com desempenho > SOMENTE depois que isso se tornar um problema. Tem pessoas que se > prendem a benchmarks do tipo: a função X me deixa fazer 32000 > operações por segundo, enquanto que a função Y me deixa fazer em 27000 > operações por segundo, então é FATO que devemos escolher a função X, > pois é mais rápida, certo? Errado. Isso não deveria ser critério de > desempate, vc deveria escolher a função que for mais clara e fácil de > testar e de dar manutenção depois (extender, reduzir, alterar, > acoplar, etc). Afinal, se você faz mais de 1000 operações por segundo > com essa função, já está usando bastante. Mas repare que, mesmo que > você faça 25000 operações *por segundo*, ambas as funções vão > continuar com desempenho imperceptivelmente parecido. Isso é um caso > típico de otimização prematura - você provavelmente não deveria nem > estar procurando saber qual é a mais rápida nesse ponto. > > Pense novamente no seu caso: o programa nem está pronto ainda. Digamos > que leve 3 segundos para rodar. E se levasse apenas 1 segundo (200% de > melhoria em desempenho!!) faria alguma diferença real? E se levasse 5, > em vez de 3? Há o caso maior também: se o seu programa leva 6 horas > pra rodar, faz diferença levar 6 horas e 20 minutos? ou 5 horas e 40 > minutos? Provavelmente não. Agora, se leva 6 horas e uma otimização o > faria rodar em apenas 35 minutos, já é algo a se pensar. > > Acredite: as pessoas normalmente passam muito mais tempo dando > manutenção a programas do que gastaram escrevendo os programas em > primeiro lugar. Se vc usar um voodoo ninja sagaz só pra satisfazer sua > sede de desempenho, vc está cometendo dois erros graves: o primeiro é > que está perdendo tempo se preocupando com desempenho antes de isso > ser um problema; e o segundo é que, dali pra frente, vc provavelmente > vai gastar muito mais tempo tentando entender o que aquilo faz, como > funciona e como resolver o pepino sem quebrar nada, do que tempo de > fato resolvendo o problema. Em outras palavras, vc agilizou o tempo de > execução mas retardou o tempo de manutenção. O problema é que > 'execução' quem faz é a máquina, mas 'manutenção' quem faz é você. > > Apenas quando o tempo de execução *realmente* se tornar um problema é > que, aí sim, vc pode procurar por gargalos. Note que não é saír > otimizando loucamente onde der, e sim observar o comportamento da > aplicação e ver onde ela *de fato* está gastando tempo. Muitas vezes > não é onde você acha. Hoje, no mundo Perl, a melhor maneira de se > identificar gargalos de desempenho é com o Devel::NYTProf > (https://metacpan.org/module/Devel::NYTProf), que te dá um diagnóstico > linha-a-linha de desempenho do seu programa. Usar é mole: > > perl -d:NYTProf meu_programa.pl # atenção: isso vai rodar o > programa!! > nytprofhtml --open > > e o seu navegador deve abrir automaticamente com os resultados! > > Você pode experimentar as diferentes soluções apresentadas nessa > thread, ou só as 4, 4.5 e 5, mas sinceramente eu perderia meu tempo > com coisas muito mais importantes como a resolução do problema em si > ou novos desafios. A menos que o desempenho desse programa realmente > esteja prejudicando o trabalho de alguém, caso em que eu rodaria o > nytprof pra saber se o problema está realmente no arquivo temporário > ou em outro lugar. Até que isso se torne um problema, como disse antes > na resposta brevíssima: não importa :) > > > []s > > -b > _______________________________________________ > Rio-pm mailing list > Rio-pm@pm.org > http://mail.pm.org/mailman/listinfo/rio-pm _______________________________________________ Rio-pm mailing list Rio-pm@pm.org http://mail.pm.org/mailman/listinfo/rio-pm