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