Recentemente, fiz uma pergunta no Stack Overflow para descobrir por que o isset () era mais rápido que o strlen () no PHP . Isso levantou questões sobre a importância do código legível e se vale a pena considerar as melhorias no desempenho de microssegundos no código.
Meu pai é um programador aposentado e eu mostrei as respostas. Ele estava absolutamente certo de que, se um codificador não considera o desempenho em seu código, mesmo no nível micro, ele não é um bom programador.
Não tenho tanta certeza - talvez o aumento no poder da computação signifique que não precisamos mais considerar esse tipo de aprimoramento de micro-desempenho? Talvez esse tipo de consideração seja das pessoas que escrevem o código de idioma real? (do PHP no caso acima).
Os fatores ambientais podem ser importantes - a Internet consome 10% da energia do mundo. Eu me pergunto como são desperdiçados alguns microssegundos de código quando replicados trilhões de vezes em milhões de sites?
Eu gostaria de saber respostas de preferência com base em fatos sobre programação.
A micro-otimização é importante na codificação?
Meu resumo pessoal de 25 respostas, obrigado a todos.
Às vezes, precisamos nos preocupar realmente com micro-otimizações, mas apenas em circunstâncias muito raras. Confiabilidade e legibilidade são muito mais importantes na maioria dos casos. No entanto, considerar a micro-otimização de tempos em tempos não faz mal. Um entendimento básico pode nos ajudar a não fazer más escolhas óbvias ao codificar como
if (expensiveFunction() || counter < X)
Deveria estar
if (counter < X || expensiveFunction())
( Exemplo de @ zidarsk8 ) Essa poderia ser uma função barata e, portanto, alterar o código seria uma micro otimização. Mas, com um entendimento básico, você não precisaria, porque escreveria corretamente em primeiro lugar.
coder does not consider performance in their code even at the micro level, they are not good programmers
é muito diferente de otimizar. É apenas uma boa codificação.Respostas:
Eu concordo e discordo de seu pai. O desempenho deve ser pensado cedo, mas a micro-otimização só deve ser pensada cedo se você realmente souber que uma porcentagem alta de tempo será gasta em pequenas seções de código ligadas à CPU.
O problema da micro-otimização é que isso geralmente é feito sem ter qualquer conceito de como os programas realmente passam mais tempo do que o necessário.
Esse conhecimento vem da experiência de ajustar o desempenho, como neste exemplo , no qual um programa aparentemente simples, sem ineficiências óbvias, é realizado através de uma série de etapas de diagnóstico e aceleração, até que seja 43 vezes mais rápido do que no início.
O que mostra é que você não pode realmente adivinhar ou intuir onde estarão os problemas. Se você realizar um diagnóstico, que no meu caso é uma pausa aleatória , as linhas de código responsáveis por uma fração significativa do tempo são expostas preferencialmente. Se você olhar para eles, poderá encontrar um código substituto e, assim, reduzir o tempo total em aproximadamente essa fração.
Outras coisas que você não corrigiu ainda levam tanto tempo quanto antes, mas, como o tempo total foi reduzido, essas coisas agora ficam com uma fração maior; portanto, se você fizer tudo de novo, essa fração também poderá ser eliminada. Se você continuar fazendo isso em várias iterações, é assim que você pode obter acelerações maciças , sem necessariamente ter feito qualquer micro-otimização .
Após esse tipo de experiência, ao abordar novos problemas de programação, você começa a reconhecer as abordagens de design que inicialmente levam a essas ineficiências. Na minha experiência, isso provém do excesso de design da estrutura de dados, da estrutura de dados não normalizada, da dependência massiva de notificações, desse tipo de coisa.
fonte
Micro-otimização é importante apenas se os números dizem que é.
Os requisitos contra os quais você está desenvolvendo devem ter alguma especificação de dados de desempenho, se o desempenho for um problema para o cliente ou usuário. Ao desenvolver software, você deve testar o desempenho do seu sistema em relação a esses requisitos. Se você não estiver atendendo aos requisitos de desempenho, precisará criar um perfil de sua base de códigos e otimizar conforme necessário para atingir os requisitos de desempenho. Quando você estiver com o desempenho mínimo exigido, não há necessidade de diminuir o desempenho do sistema, especialmente se você comprometer mais a legibilidade e a manutenção do código (na minha experiência, o código altamente otimizado é menos legível e sustentável, mas nem sempre). Se você pode obter ganhos adicionais de desempenho sem degradar os outros atributos de qualidade do sistema,
No entanto, há casos em que o desempenho é da maior importância. Estou pensando principalmente em sistemas em tempo real e sistemas embarcados. Em sistemas em tempo real, alterar a ordem das operações pode ter um efeito enorme no cumprimento dos prazos rígidos necessários para a operação adequada, talvez até influenciando os resultados dos cálculos. Em sistemas embarcados, você normalmente possui memória, potência da CPU e energia limitadas (como na energia da bateria), portanto, é necessário reduzir o tamanho dos binários e o número de cálculos para maximizar a vida do sistema.
fonte
Sempre que alguém pergunta sobre otimização , lembro-me da citação de Michael A. Jackson
Citação da Wikipedia corrigida para inglês britânico. * 8 ')
Implícito na segunda regra é criar um perfil do seu código e gastar apenas tempo otimizando coisas que farão a diferença.
Ao programar em montagem, a afirmação de seu pai estava correta. Mas isso é muito mais próximo do metal do que a maioria das pessoas programa atualmente. Hoje, mesmo a tentativa de otimizar a si mesmo (sem criação de perfil) pode resultar em uma execução mais lenta do código do que se você tivesse feito algo da maneira mais comum, pois é mais provável que a maneira comum seja otimizada pelos compiladores JIT modernos .
Mesmo em C, você precisa ser muito bom em otimização para saber mais sobre como otimizar uma seção de código do que o compilador.
Se você não está familiarizado com muito do que Ulrich Drepper fala em seu excelente artigo O que todo programador deve saber sobre memória , provavelmente está perdendo, mesmo tentando otimizar a si mesmo. Porém, ao contrário do título dos trabalhos (que na verdade é uma homenagem à igualmente fantástica O que todo cientista da computação deve saber sobre aritmética de ponto flutuante ) não ter esse nível de entendimento não o impede necessariamente de ser um bom programador, apenas um tipo diferente de programador.
isset()
vs.strlen()
em PHPEu não sei PHP, então realmente não é óbvio o que
isset()
se deve fazer. Posso inferir isso a partir do contexto, mas isso significa que será igualmente obscuro para programadores PHP iniciantes e pode até fazer com que programadores mais experientes dêem uma olhada dupla. Esse é o tipo de uso idiomático de uma linguagem que pode tornar a manutenção um pesadelo.Não apenas isso, mas não há garantia de que
isset()
sempre será mais eficiente, apenas porque é mais eficiente agora. Uma otimização agora pode não ser uma otimização no próximo ano ou em 10 anos. CPUs, sistemas, compiladores melhoram e mudam com o tempo. Se o desempenho do PHPstrlen()
for um problema, o PHP poderá ser modificado no futuro, então todas as otimizações isset () podem precisar ser removidas para otimizar o código mais uma vez.Toda otimização tem o potencial de se tornar uma anti-otimização futura ; portanto, deve ser considerado um possível odor de código, a ser mantido no mínimo.
Um exemplo da experiência pessoal
Como exemplo dessa anti-otimização , uma vez eu tive que higienizar uma enorme base de código cheia de código do formulário,
if x==0 z=0 else z=x*y
porque alguém assumiu que um ponto flutuante multiplicado sempre seria mais caro que um ramo. Na arquitetura de destino original, essa otimização fez o código executar uma ordem de magnitude mais rápido, mas os tempos mudam.Quando tentamos usar esse código em uma CPU mais moderna, com alto fluxo de pipeline, o desempenho foi horrivelmente ruim - cada uma dessas instruções causa uma descarga de pipeline. Simplificar todas essas linhas de código para que
z=x*y
o programa execute uma ordem de magnitude mais rapidamente na nova arquitetura, restaurando o desempenho perdido pela anti-otimização .Os problemas que normalmente temos que otimizar para hoje são muito diferentes daqueles que tivemos que otimizar há 20 ou 10 anos atrás.
Então nos preocupamos em fazer o máximo de trabalho por ciclo de clock, agora é mais provável que nos preocupemos com liberações de pipeline, previsões incorretas de ramificações e falhas de cache no nível da CPU, mas os bloqueios e a comunicação entre processos estão se tornando muito mais significativos à medida que avançamos para o multi- arquiteturas de processo e multiprocessador. O artigo de Drepper pode realmente ajudar a entender muitas dessas questões.
fonte
Como regra geral: 95% do seu código é executado 5% do tempo. Não há sentido em otimizar antes de criar um perfil / comparar o seu código e ver quais são os 5% que são executados 95% das vezes.
Todo idiota pode fazer micro-otimização e qualquer compilador / tempo de execução decente fará isso por você.
A otimização do bom código é trivial. Escrever código otimizado e tentar torná-lo bom depois disso é tedioso na melhor das hipóteses e insustentável na pior.
Se você se preocupa seriamente com desempenho, não use PHP para código crítico de desempenho. Encontre os gargalos e reescreva-os com extensões C. Mesmo otimizar seu código PHP além do ponto ofuscante, você não terá tanta velocidade.
Pessoalmente, gostei muito da micro-otimização quando comecei a programar. Porque é óbvio. Porque recompensa você rapidamente. Porque você não precisa tomar decisões importantes. É o meio perfeito de procrastinação. Permite fugir das partes realmente importantes do desenvolvimento de software: o design de sistemas escaláveis, flexíveis, extensíveis e robustos.
fonte
Eu concordaria com seu pai: "Se um codificador não considera o desempenho em seu código, mesmo no nível micro, ele não é um bom programador". A chave é "considerar o desempenho". Isso não é equivalente a "fazer micro-otimizações a cada passo".
Concordo com a maioria dos outros comentários - o que costumava tornar os programas C mais rápidos hoje em dia - mas há outras coisas sérias a serem consideradas: Devo usar C ou C ++? Classes com operadores sobrecarregados simples podem prejudicar o desempenho se você as usar muito. Isso importa? Depende da sua aplicação, mas se você nem considerar, você não é um bom programador. Algumas pessoas podem considerá-lo por cerca de 2 milissegundos e descartá-lo, mas acho que muitos literalmente nem o consideram.
A realidade é que, com a otimização, o código pode ficar mais difícil de ler. O código levará mais tempo para escrever. O código estará entre um pouco mais rápido e uma ordem de magnitude mais rápida (isso é raro). Seus clientes provavelmente não saberão a diferença.
Outra realidade é que as pessoas gostam de reutilizar código, e onde ele acaba pode ser bem diferente do que quando você o escreveu. De repente, as pessoas podem se importar.
Como exemplo, digamos que você escreveu algo como Angry Birds em um PC ou em um console de jogos. Você desconsiderou a otimização em seu sistema de física e em seu sistema gráfico - porque os núcleos duplos de 2,5 GHz são basicamente o mínimo hoje em dia, e seu jogo funciona suficientemente bem. Em seguida, os telefones inteligentes aparecem e você deseja portá-lo. Oh caramba, um núcleo ARM de 600 MHz ?
Pense em um site - algo reunido em um fim de semana como Hot or Not . Você usa qualquer banco de dados útil, escreve tudo com o desenvolvimento rápido em mente, iniciando enviando um URL para seus amigos. Três meses depois, seu servidor está morrendo de sobrecarga e não há nada que você possa fazer para aumentar a escala. Isso acontece o tempo todo. Os maiores sites têm contas de energia medidas em centenas de quilowatts ou mesmo megawatts. Pense nisso: existem megawatts a serem salvos por meio da otimização de código.
Como seu pai disse, você deve pelo menos considerar . A maioria das pessoas nem sabe quanto desempenho está em cima da mesa e o encobre com uma rápida piada sobre "otimização prematura" e "não faça". Estes não são bons programadores.
Esta não é uma opinião popular sobre esses sites. Tchau, pontos de reputação ....
fonte
Vamos primeiro considerar o seu caso: PHP
Em geral,
Eu não gastaria muito tempo "TOOOOO" otimizando meu código em uma linguagem dinâmica como Python ou Ruby - porque eles NÃO foram projetados para tarefas de processamento de números intensivos da CPU. Eles resolvem diferentes classes de problemas em que modelar uma situação do mundo real de maneira elaborada (que é fácil de ler e manter) - que é chamada de expressividade - é mais importante que a velocidade. Se a velocidade fosse a principal preocupação, eles não seriam dinâmicos em primeiro lugar.
Para programas compilados (C ++, Java), a otimização é mais crucial. Mas também é preciso primeiro examinar a natureza / domínio / objetivo do programa que você está escrevendo. Você também deve ponderar cuidadosamente o tempo para otimizar com os ganhos dessa otimização. Se você precisar de mais otimização, considere dar um passo para baixo - e codifique essas partes do seu código no assembler.
Portanto, para responder à sua pergunta original - "A micro-otimização é importante ao codificar?" - a resposta é - DEPENDE -
Além de consumir muito tempo, a micro-otimização (otimização de código) também "distorce" a legibilidade natural do seu código, tornando-o pesado em manutenção. Sempre considere o último recurso - tente sempre otimizar todo o aplicativo adotando hardware e arquitetura melhores do que otimizar arquivos de código individuais.
fonte
Parece haver muitas respostas que dizem que a micro otimização é
Mas bem, eu sei que existem algumas otimizações em que não há impacto na legibilidade, e eu apenas gosto de fazer isso por diversão. Vi em algumas de minhas tarefas escolares (todas baseadas na velocidade) que sempre é bom considerar a micro otimização ao escrever declarações condicionais como:
é sempre melhor do que
Existem algumas maneiras de "acelerar" seu código dessa maneira e a diferença geralmente é insignificante (nem sempre), mas me sinto melhor se escrever dessa maneira.
Não sei se alguém considera isso como uma otimização, mas acho que um programador deve saber e considerar essas coisas ao escrever seu código.
fonte
cheap() && expensive()
é uma otimização,expensive () && cheap()
convida as pessoas a substituírem cegamente uma pela outra, sem levar em consideração a significativa mudança semântica que ela cria (em idiomas onde&&
é o operador de curto-circuito).if (x<100 && isPrime(x))
, apenas para deixar mais claro.No início de minha carreira, declarações abrangentes como "não otimizar micro" levaram a muita confusão. Tudo é circunstancial; portanto, a razão pela qual as pessoas dizem "melhor prática" em vez de "fazer isso".
A "melhor prática" é a melhor opção, considerando todas as circunstâncias. Por exemplo, LINQ e Entity Framework devem ser usados no lugar de SQL embutido. Na minha empresa, estamos no SQL Server 2000 . O SQL Server 2000 não oferece suporte ao Entity Framework. As melhores práticas exigem:
Sei por experiência própria que isso não vai acontecer. Então, eu poderia sair, insistir sem fim ou não seguir as melhores práticas.
Há considerações políticas, técnicas e monetárias por trás das decisões que afetam o resultado geral. Lembre-se desse fato ao tomar uma decisão e escolha suas batalhas com sabedoria.
" Para tudo, há uma estação, um tempo para todas as atividades sob o céu " .
fonte
LINQ and Entity Framework should be used in lieu of inline SQL
- Até que você realmente precise do SQL embutido para otimizar alguma coisa; o SQL que a EF produz nem sempre é ideal.Isso é sempre uma troca.
Primeiro, a indústria de computadores trata de dinheiro no final. O que você precisa fazer como desenvolvedor é gerar valor para o cliente para obter dinheiro (isso é uma simplificação excessiva, mas o ponto principal está aqui).
O tempo do desenvolvedor custa dinheiro. A energia da máquina também custa dinheiro. Normalmente, esse segundo custo é bem menor que o primeiro. Portanto, é importante ter um código legível e código de manutenção, para que o desenvolvedor possa passar a maior parte do tempo agregando valor.
A micro-otimização pode, em alguns casos, ser importante. Mas eles geralmente envolvem código menos legível ou código menos extensível (esse não é o caso do seu exemplo vinculado, mas, em geral, é). Isso vai custar em algum momento do desenvolvedor. Desta vez, sendo mais caro que a energia da máquina, isso é um desperdício.
Segundo, a micro-otimização em um grande projeto pode tornar cada vez mais difícil manter / evoluir. O problema disso é que, ao evoluir, pode ser impossível fazer outra otimização. Com um aplicativo em evolução, você normalmente acaba com uma solução mais lenta do que você teria sem fazer essas otimizações.
Terceiro, a otimização é muitas vezes irrelevante, pois a complexidade do algoritmo geralmente supera qualquer micro-otimização que você poderia ter feito se o conjunto de dados crescer. Infelizmente, como a micro-otimização torna seu código mais difícil de manter / evoluir, essa otimização pode ser mais difícil de fazer.
Em algum momento, o valor está nessa otimização (pense em programas críticos de latência, como em videogames ou no piloto automático de uma aeronave). Mas isso tem que ser demonstrado. Normalmente, seu programa passa a maior parte do tempo em uma parte limitada do código. Seja qual for a micro-otimização que você faz, você nunca terá seus programas com valor mais rápido sem identificar o gargalo e trabalhar nessa parte.
Ao fazer sua pergunta, você mostrou que não comparou o problema em um programa real. Nesse caso, você poderia fazer o truque e perceber se era mais rápido ou não. Então você estava perguntando isso antes de ter qualquer problema. É aqui que está o problema. Você estava lidando com o problema de otimização da maneira errada.
Como a manutenção e a evolução são geralmente mais valiosas que a micro-otimização, certifique-se de ter a interface certa antes de fazer qualquer. Então, se partes do seu programa são abstratas o suficiente uma para a outra, você pode otimizar uma micro sem estragar tudo. Isso requer que sua interface esteja em execução por tempo suficiente para ser confiável.
fonte
O desempenho é um recurso
O artigo de Jeff Atwood é excelente para criar um site de alto desempenho e a importância de fazê-lo ...
Dito isto, não se concentre na micro-otimização até que você precise. Há uma otimização mais econômica que você pode executar. Concentre-se na arquitetura, não no código. A maioria dos sites que vi com desempenho lento apresentava problemas de alto nível (camada desnecessária de serviços da web, design de banco de dados ruim, arquiteturas excessivamente complicadas) que não apenas afetavam adversamente o desempenho, mas estavam profundamente arraigados e difíceis de corrigir.
Ao criar um site, o código do lado do cliente e a lógica do banco de dados têm muito mais probabilidade de causar problemas de desempenho do que o código do lado do servidor. Como qualquer outra coisa, se você tiver problemas de desempenho, saberá ainda melhor o perfil do seu código e poderá encontrá-los logo no início.
fonte
O tempo do desenvolvedor custa mais que o tempo do computador. Geralmente, é isso que você deseja otimizar. Mas:
select (select count(*) from foo) >= 1
não é a mesma coisa queselect exists(select 1 from foo)
.fonte
O que você deseja otimizar?
"Otimizar" nem sempre significa fazer com que o código seja executado o mais rápido possível. Há momentos em que é importante encontrar a maneira mais rápida de fazer algo, mas isso não é tão comum na maioria dos códigos. Se os usuários não perceberem a diferença entre 50 e 100 microssegundos, não há efetivamente nenhuma diferença entre os dois no código que será executado apenas ocasionalmente. Aqui está um exemplo:
Se você precisar atualizar continuamente uma exibição da duração da entrada do usuário e da quantidade de tempo que leva para uma das duas rotinas para determinar que a duração é muito menor que o tempo entre dois pressionamentos de tecla consecutivos, realmente não importa qual rotina você usa. Por outro lado, se você precisar determinar o tamanho de um bilhão de strings, provavelmente desejará prestar muita atenção às diferenças de desempenho entre diferentes rotinas. No primeiro caso, você pode preferir escrever um código fácil de entender e verificar; no segundo caso, você pode estar disposto a trocar legibilidade por velocidade.
De qualquer forma, se você deseja otimizar seu código, analise seu código antes e depois das alterações que você fizer. Hoje em dia, os programas são complicados o suficiente para que seja difícil dizer onde estão os gargalos; a criação de perfil ajuda a otimizar o código certo e depois mostra que as otimizações que você fez realmente funcionaram.
Você não disse quando seu pai se aposentou ou que tipo de programação ele fez, mas a reação dele não é surpreendente. Historicamente, memória, armazenamento secundário e tempo de computação eram todos caros e, às vezes, muito caros. Hoje em dia, todas essas coisas se tornaram muito baratas em comparação ao tempo do programador. Ao mesmo tempo, processadores e compiladores tornaram-se capazes de otimizar o código de maneiras que os programadores nunca poderiam corresponder. Os dias em que os programadores usam pequenos truques para incluir algumas instruções da máquina aqui e ali desaparecem.
fonte
Não é importante otimizar ao escrever o código. A otimização deve ser feita com a ajuda de um criador de perfil, otimizando o código onde for importante.
NO ENTANTO , um programador deve tentar evitar coisas obviamente estúpidas enquanto escreve o código.
Por exemplo, não faça operações caras repetidas dentro de um loop. Armazene o valor em uma variável fora do loop e use-o. Não faça coisas como comparações de strings ou regex repetidamente em uma função frequentemente chamada, quando você puder subir um nível, fazer a comparação e transformá-la em um número inteiro, uma referência de função ou uma classe derivada.
Essas coisas são fáceis para um programador experiente lembrar e quase sempre melhoram a qualidade do código.
fonte
Ao decidir o que otimizar, lembre-se sempre da lei de Amdahl . Veja o link para matemática precisa; a declaração concisa a lembrar é:
É por isso que as pessoas sempre dizem que não vale a pena otimizar partes do seu programa que não ocupam mais do que alguns por cento do tempo de execução total. Mas esse é apenas um caso especial de um princípio mais geral. A lei da Amdahl diz que, se você precisar executar o programa inteiro duas vezes mais rápido, precisará acelerar cada peça em média 50%. Ele informa que, se você precisar processar vinte gigabytes de dados, existem apenas duas maneiras de fazê-lo ir mais rápido do que o tempo necessário para ler vinte gigabytes do disco: obtenha um disco mais rápido ou reduza os dados.
Então, o que a lei de Amdahl diz sobre micro-otimizações? Diz que talvez valham a pena se aplicar de maneira geral. Se você pode economizar um por cento do tempo de execução de todas as funções do seu programa, parabéns! Você acelerou o programa em um por cento. Valeu a pena fazer isso? Bem, como um compilador, eu ficaria encantado em encontrar uma otimização que fizesse isso, mas se você estiver fazendo isso manualmente, diria que procure algo maior.
fonte
Depende do estágio de desenvolvimento em que você está, ao começar a escrever algo inicialmente, as micro-otimizações não devem ser levadas em consideração, pois você obterá mais ganhos de desempenho usando bons algoritmos do que as micro otimizações. Além disso, considere o que você está desenvolvendo, pois os aplicativos sensíveis ao tempo terão mais benefícios das considerações de micro otimização do que os aplicativos comerciais genéricos.
Se você estiver testando e ampliando o software, as micro-otimizações provavelmente o prejudicarão, pois tendem a dificultar a leitura do código e até a introduzir seu próprio conjunto exclusivo de bugs que precisam ser corrigidos, juntamente com qualquer outra coisa que precise ser corrigida.
Se você está realmente recebendo reclamações dos usuários sobre código lento, vale a pena considerar, mas apenas se tudo o mais tiver sido resolvido, a saber:
Se todas essas perguntas tiverem sido respondidas e você ainda estiver com problemas de desempenho, talvez seja hora de começar a usar micro-otimizações no código, mas é provável que outras alterações (ou seja, melhor código, melhor algoritmo, etc.) irão lhe render mais um ganho de desempenho do que uma micro-otimização.
fonte
A velocidade de execução é um dos muitos fatores que contribuem para a qualidade de um programa. Muitas vezes, a velocidade tem uma correlação inversa com a legibilidade / manutenção. Em quase todos os casos, o código deve ser legível por humanos, para que possa ser mantido. O único momento em que a legibilidade pode ser comprometida é quando a velocidade é um requisito essencial. O requisito de tornar o código mais rápido do que a capacidade de legibilidade / capacidade de manutenção total quase nunca é aplicável, mas há certos casos em que isso ocorre. O principal a lembrar é que o código micro-otimizado geralmente é código hacky; portanto, a menos que haja um requisito definido em algum lugar, é quase sempre a maneira errada de resolver o problema. Por exemplo, o usuário quase nunca notará a diferença entre os tempos de execução de 0,5 segundo e 1 segundo nas operações CRUD, portanto, você não precisa entrar em um assembly-interop-hackfest para chegar a 0,5 segundos. Sim, eu poderia pilotar um helicóptero para trabalhar e seria 10 vezes mais rápido, mas não o faço pelo preço e pelo fato de o helicóptero ser muito mais difícil de pilotar.Quando você otimiza o código desnecessariamente, é exatamente isso que você está fazendo: adicionando complexidade e custo desnecessários para alcançar uma meta supérflua.
fonte
A micro otimização é importante quando você atinge uma restrição. O que lhe interessa pode ser a memória, a taxa de transferência, a latência ou o consumo de energia. Observe que essas são características no nível do sistema; você não precisa (e não pode) otimizar todas as funções de todas as maneiras.
É mais provável que os sistemas embarcados precisem de micro-otimização porque as restrições são atingidas com mais facilidade. No entanto, até mesmo a micro-otimização apenas leva você até agora; você não pode otimizar sua maneira de sair de um design ruim. O ponto sobre o bom design em um sistema é que você pode raciocinar sobre o sistema como um todo. Os componentes que precisam de micro otimização devem ser perfeitamente expostos e otimizados de uma maneira que não comprometa o design do sistema.
Observe que os pequenos sistemas "incorporados" hoje em dia podem estar bem próximos dos Vaxen ou PDP-11 do passado, portanto esses problemas costumavam ser mais comuns. Em um sistema moderno de uso geral que executa computação comercial geral moderna, a micro-otimização é rara. Provavelmente, isso é parte do motivo pelo qual seu pai assume a posição que ele faz.
No entanto, não importa se você está lidando com nanossegundos, milissegundos, segundos ou horas; os problemas são os mesmos. Eles precisam ser avaliados no contexto do sistema e no que você está tentando alcançar.
Este é um exemplo de uma pergunta recente que respondi no Stack Overflow para um caso em que a micro-otimização era necessária: codificadores de vídeo de código aberto para um sistema incorporado .
fonte
O maior problema com a micro-otimização é que ele leva a escrever um código mais difícil de manter.
Outro problema é que, dependendo da configuração do computador, às vezes sua micro-otimização pode ter um desempenho pior do que sem a 'otimização'.
Fazer muitas micro-otimizações consumirá muito tempo lutando contra algo que realmente não importa.
Uma abordagem melhor é tornar um código mais limpo, mais fácil de manter e, se você tiver problemas de desempenho, execute um perfil para descobrir o que realmente está tornando seu código lento. E sabendo exatamente o que é realmente ruim, você pode corrigi-lo.
Não estou dizendo que não fazer micro-otimizações é desculpa para escrever código estúpido.
fonte
Se você começar a se preocupar com milissegundos, considere desistir do PHP e usar C ou Assembly. Não que eu queira fazer isso, não faz sentido discutir esses números e usar uma linguagem de script. Seu código interage com esse comando com frequência?
Os fatores ambientais estão fora de questão aqui, esses servidores são executados 24 horas por dia, sete dias por semana, e se eles realmente processam algo, isso só importa se for realmente uma tarefa em execução por um período muito longo.
Provavelmente, a luz do seu escritório e a energia que nossos computadores usaram enquanto todos digitamos perguntas e respostas, gastaram muito mais energia do que qualquer tipo de micro otimização que você possa aplicar razoavelmente aos seus aplicativos economiza.
fonte
Você deve escolher o melhor algoritmo simples para a tarefa. O motivo de ser simples é manter o código legível. O motivo pelo qual ele precisa ser o melhor é evitar começar com características de tempo de execução ruins. Não escolha cegamente o BubbleSort quando souber que terá grandes conjuntos de dados. É bom, no entanto, para o tipo ocasional de 10 elementos.
ENTÃO, se os números de criação de perfil mostrarem que sua escolha do melhor algoritmo simples não foi boa o suficiente, você poderá iniciar a otimização (que geralmente é o custo da legibilidade).
fonte
start out with bad runtime characteristic
não comece deliberadamente com uma característica de tempo de execução ruim.Eu já disse isso antes e vou dizer aqui: "A otimização prematura é a raiz de todo mal" . Essa deve ser uma das regras no centro da mente de qualquer programador.
O código pode, até certo ponto, sempre ser mais rápido do que atualmente. A menos que você esteja montando manualmente a embalagem com um chip em mente, sempre há algo a ser ganho com a otimização. No entanto, a menos que você queira montar uma embalagem manual para tudo o que faz, deve haver uma meta quantitativa que, quando você se encontra, você diz "basta" e para de otimizar, mesmo que ainda exista um olhar ofuscante por desempenho. você na cara.
Um código bonito, elegante e extremamente eficiente é inútil se não funcionar (e por "trabalho" quero dizer produzir a saída esperada, considerando todas as entradas esperadas). Portanto, produzir código que funcione SEMPRE deve ser a primeira prioridade. Depois que funciona, você avalia o desempenho e, se estiver faltando, procura maneiras de melhorá-lo, até o ponto em que é bom o suficiente.
Há algumas coisas que você precisa decidir antecipadamente que afetarão o desempenho; decisões muito básicas, como qual idioma / tempo de execução você usará para implementar esta solução. Muitos deles impactarão o desempenho em muitas ordens de magnitude mais do que chamar um método contra outro. Honestamente, o PHP, como linguagem de script, já é um problema de desempenho, mas como poucos sites com script são criados de baixo para cima em C / C ++, é comparável a outras tecnologias que você provavelmente escolheria (Java Servlets, ASP.NET etc).
Depois disso, o tamanho da mensagem de E / S é o seu próximo maior desempenho. A otimização do que você lê e grava no disco rígido, portas seriais, canais de rede etc. geralmente melhorará o tempo de execução do programa em muitas ordens de magnitude, mesmo que os algoritmos por trás das operações de E / S sejam eficientes. Depois disso, reduza a complexidade Big-O do próprio algoritmo e, se for absolutamente necessário, você pode "otimizar" escolhendo opções de método mais baratas e tomando outras decisões esotéricas em níveis baixos.
fonte
Você menciona que seu pai é um programador aposentado. Os programadores que trabalhavam no mundo do mainframe precisavam se preocupar muito com o desempenho. Lembro-me de estudar uma atividade da Marinha dos EUA em que seu mainframe estava restrito por hardware a 64 KB de memória por usuário. Nesse mundo da programação, você tem que procurar cada pouquinho que puder.
As coisas estão muito diferentes agora e a maioria dos programadores não precisa se preocupar tanto com micro-otimizações. No entanto, os programadores de sistemas embarcados ainda o fazem e as pessoas do banco de dados ainda precisam usar código otimizado.
fonte
O código deve ser escrito para ser absolutamente claro sobre o que ele faz. Então, se e somente se estiver muito lento, volte e acelere. O código sempre pode ser alterado para ser mais rápido mais tarde, se puder ser entendido - mas boa sorte mudando para ficar claro se for rápido.
fonte
É importante se:
1) A vida de alguém depende do seu código. Uma função que leva 25ms para ser executada no monitor de freqüência cardíaca de alguém é provavelmente uma má ideia.
Pessoalmente, adoto uma abordagem em duas frentes - existem micro-otimizações que você pode fazer que não afetam a legibilidade - obviamente você deseja usá-las. Mas se isso afeta a legibilidade, espere - você não obterá muitos benefícios e poderá levar mais tempo para depurar a longo prazo.
fonte
Não, considerando que existem plataformas como JVM e .NET em que o código é escrito para uma máquina virtual e, portanto, tentar otimizar a execução pode não funcionar tão bem quanto o que é ideal na área de trabalho de um desenvolvedor não é necessariamente o mesmo em um servidor. Veja a que distância do hardware algumas dessas peças de software de alto nível estão em outro ponto aqui. Algo a considerar é dada a diversidade de hardware, quão realista é otimizar o código para chips específicos, como uma CPU ou GPU, quando um novo modelo provavelmente será lançado em menos de um ano?
Outra questão aqui a considerar é o desempenho medido por qual métrica: velocidade de execução, memória usada na execução, velocidade de desenvolvimento de novos recursos, tamanho da base de código em um servidor em formas compiladas ou descompiladas, escalabilidade, manutenção, etc. .? Se for tomada de maneira ampla o suficiente, a pergunta se torna trivial, mas não tenho certeza de quão amplamente você pretendia levar o desempenho tão real que pode ser quase qualquer coisa, desde que possa ser medido de alguma maneira.
Algumas micro-otimizações podem funcionar e outras podem não funcionar, e é aí que se pode pensar em quanto vale a pena executar esse trabalho em comparação com outro trabalho que pode ser visto como uma prioridade muito maior, como novos recursos ou correção de bugs. A outra pergunta seria se uma atualização de hardware ou software também pode interromper algumas dessas otimizações.
fonte
Eu acho que há uma grande diferença entre boa programação e micro-otimização.
Se houver duas maneiras de executar a mesma tarefa, uma sendo mais rápida que a outra e ambas com a mesma legibilidade, você deve usar a mais rápida. Sempre. E isso é uma boa programação. Não há razão para não usar um algoritmo melhor para resolver um problema. E mesmo documentando isso é fácil: forneça o nome do algoritmo, todos poderão pesquisar no Google e encontrar mais informações sobre como ele funciona.
E bons algoritmos já estão otimizados. Eles serão rápidos. Eles serão pequenos. Eles usarão a memória mínima necessária.
Mesmo se usá-los, seu programa ainda não possui esse desempenho, você pode considerar a otimização micro. E você precisará realmente conhecer o idioma para poder otimizar.
E sempre há espaço para gastar mais dinheiro em hardware. O hardware é barato, os programadores são caros . Não gaste muito tempo / dinheiro otimizando quando você pode apenas comprar hardware.
fonte
A legibilidade do código IMHO é mais importante que a micro otimização, porque na maioria dos casos a micro otimização não vale a pena.
Artigo sobre micro-otimizações sem sentido :
Portanto, na maioria dos casos, a micro-otimização economiza 1 operação entre milhões, mas piora a legibilidade.
fonte
Outras respostas estão certas no dinheiro. Mas vou acrescentar outro ponto em que é preciso diferenciar o que é otimização / micro-otimização prematura e escrever código de desempenho que reflita uma compreensão do comportamento das construções de linguagem / estrutura (desculpe, não consegui encontrar uma palavra para o último) . O último é uma boa prática de codificação e geralmente se deve fazer!
Eu vou explicar A otimização ruim (leitura prematura / micro otimização) não ocorre quando você otimiza seções de código sem criar um perfil para saber se realmente são os gargalos. É quando você otimiza com base em suas suposições, boatos e comportamentos não documentados. Se está documentado e faz algo de uma maneira mais eficiente / lógica , por menor que seja, eu chamo de boa otimização . Como outros já declararam, ambos têm contras e quase nenhum profissional, no que diz respeito a ganhar bons negócios, mas ainda assim faço o último, não o primeiro, se isso não prejudica totalmente a legibilidade. Sim, a legibilidade / manutenção é da maior importância e é sobre onde você deve traçar a linha.
Reiterarei os pontos apontados por outros aqui como a futilidade de otimizações boas e ruins:
Suas dependências para um problema específico podem mudar e qualquer tempo gasto na otimização antes de concluir a seção lógica do seu aplicativo é uma perda de tempo. Quero dizer, otimizar em um estágio relativamente inicial. Hoje você tem um
List<T>
e quando o aplicativo é enviado, você precisa alterá-loLinkedList<T>
e agora todo o benchmarking era uma perda de tempo e esforço.Principalmente, o gargalo real do seu aplicativo (lido como diferença mensurável) pode ser de 5% do seu código (principalmente o sql) e a otimização dos outros 95% não oferece benefícios a seus clientes.
Normalmente, o código "tecnicamente" com melhor desempenho significa mais verbosidade, o que, por sua vez, significa mais código propenso a erros, o que, por sua vez, significa manutenção mais difícil e mais tempo gasto, o que, por sua vez, significa que você ganha menos dinheiro.
A pegada de carbono que você economiza para o mundo inteiro com 1% de ganho de desempenho é facilmente reduzida pelos gases de efeito estufa que sua equipe precisará emitir ao depurar e manter esse código.
Os negativos da otimização ruim, em particular, são:
Não costuma dar o desempenho que você espera. Veja esta pergunta no SO, onde as otimizações deram errado . De fato, pode ter efeitos adversos. Esse é o problema com o comportamento não documentado.
De qualquer forma, os compiladores modernos farão isso por você.
Vou dar alguns exemplos de otimização ruim e boa:
O mal -
uso de tipos inteiros menores em vez de
Int32
.++i
usado em vez dei++
for
em vez deforeach
(o pior que eu já vi, derrota totalmente a lógica)evitando variáveis fechadas
usando em
char
vez de string durante a concatenação de string, como:O bom (do mundo .NET. Deve ser auto-explicativo) -
Pesquisa dupla
ao invés de
Carregue todos
ao invés de
Fundição em dois estágios:
ao invés de
Se o pedido não importa
ao invés de
Boxe
ao invés de
Se você me perguntar se isso oferece benefícios visíveis de desempenho, eu diria que não. Mas eu sugeriria que se devesse usá-las porque decorre de uma compreensão do comportamento dessas construções. Por que fazer duas chamadas quando você pode fazer apenas 1? Do ponto de vista filosófico, é uma boa prática de codificação. E 1 e 3 também são um pouco menos legíveis em termos estritos, mas eles superam a legibilidade? Não, não muito, então eu uso. Agora essa é a chave - manter um desempenho decente em relação à legibilidade. E quando é isso, é sobre onde você desenha a linha.
fonte
"Vale a pena" precisa de contexto, como o mais simples de escrever, ler e manter, e o quanto mais rápido torna algo para o usuário muito mais responsivo e interativo, exigindo menos tempo para esperar.
Economizar alguns centavos para comprar uma lata de refrigerante não me fará muito bem se eu tiver que percorrer uma distância para economizar esses centavos, principalmente porque raramente tomo refrigerante hoje em dia. Economizar alguns centavos por lata na compra de um milhão de latas de refrigerante pode ser um grande negócio.
Enquanto isso, economizo alguns centavos quando duas pessoas estão ao meu lado e uma oferece exatamente a mesma coisa por algumas mais baratas e a outra não, e eu escolho a mais cara porque gosto mais do chapéu delas, parece um caso tolo de pessimização.
O que costumo encontrar pessoas chamando de "micro-otimizações" parece curiosamente desprovido de medições, contexto e discussão do usuário, quando deveriam existir os três para considerar essas otimizações, caso não sejam triviais. Para mim, uma micro otimização adequada hoje em dia está relacionada a coisas como layouts de memória e padrões de acesso e, embora possam parecer "micro" em foco, eles não são micro em efeito.
Consegui, há pouco tempo, reduzir uma operação de 24 segundos para 25 milissegundos (cerca de 960 vezes mais rápido), com saídas idênticas (protegidas por testes automatizados), sem alteração na complexidade algorítmica, para a cobertura volumétrica de difusão de calor, através de "micro-otimizações" (a maior das quais veio de uma alteração no layout da memória, que reduziu para cerca de 2 segundos, o restante foram coisas como SIMD e análises adicionais de falhas de cache no VTune e algum rearranjo adicional do layout da memória).
Wolfire explica a técnica aqui e lutou com o tempo necessário: http://blog.wolfire.com/2009/11/volumetric-heat-diffusion-skinning/
Minha implementação conseguiu fazer isso em milissegundos enquanto ele lutava para reduzi-lo a menos de um minuto:
Depois que eu "otimizei" o micro de 24 segundos para 25ms, isso mudou o fluxo de trabalho. Agora, os artistas podem mudar suas plataformas em tempo real a mais de 30 FPS sem esperar 24 segundos cada vez que fazem pequenas alterações em suas plataformas. E isso realmente mudou todo o design do meu software, já que eu não precisava mais da barra de progresso e coisas desse tipo, tudo se tornou interativo. Portanto, isso pode ser uma "micro-otimização" no sentido de que todas as melhorias ocorreram sem nenhuma melhoria na complexidade algorítmica, mas foi uma "mega-otimização" em vigor que tornou o que antes era um processo doloroso e não interativo. para um interativo em tempo real que mudou completamente a maneira como os usuários trabalhavam.
Medição, Requisitos de Usuário Final, Contexto
Gostei muito do comentário de Robert aqui e talvez não tenha conseguido expressar o que queria:
Apesar de trabalhar em um campo muito crítico para o desempenho, com requisitos frequentemente em tempo real, é o único momento em que considero qualquer micro-otimização que exija que eu saia do meu caminho.
E eu enfatizaria não apenas as medições, mas também o lado do usuário. Sou uma pessoa estranha porque cheguei ao meu campo atual (e anteriormente gamedev) como usuário / fã primeiro, desenvolvedor segundo. Portanto, nunca fiquei tão empolgado com as coisas usuais que empolgam os programadores como resolver quebra-cabeças técnicos; Achei um fardo para eles, mas aguentaria com eles o sonho do usuário final que compartilhei com outros usuários. Mas isso me ajudou a garantir que, se eu estivesse otimizando alguma coisa, teria um impacto real nos usuários com benefícios reais. É minha salvaguarda contra a otimização micro sem rumo.
Isso é realmente tão importante quanto o criador de perfil na minha opinião, porque eu tive colegas que fizeram coisas como otimizar a subdivisão de um cubo em um bilhão de facetas apenas para engasgar com modelos de produção do mundo real, como personagens e veículos. O resultado foi impressionante em algum sentido de "demonstração tecnológica", mas quase inútil para os usuários reais, porque eles estavam criando perfis, medindo e comparando casos que não estavam alinhados com os casos de uso do mundo real. Portanto, é muito importante entender primeiro o que é importante para os usuários, aprendendo a pensar e usar o software como um ou colaborando com eles (idealmente ambos, mas pelo menos colaborando com eles).
fonte
isset
vs.strlen
parece mais minúsculo em foco ausente o contexto e as medidas. :-DVou colocar desta maneira - a micro-otimização é um processo de otimização de algo que não é um gargalo. Por exemplo, se seu programa chama duas funções A e B, e A leva 100 milissegundos para ser concluído e B leva 2 microssegundos, e você continua otimizando a função B. Isso não é apenas importante, é absolutamente errado. Mas a função de otimização B é chamada de otimização e não de micro-otimização. A importância da otimização depende. Diga que você não tem mais nada a fazer e seu programa está livre de erros; então, sim, é importante. Mas geralmente você tem prioridades. Digamos que você precise adicionar / gravar a função C. Se você acha que a função de gravação C lhe renderá mais dinheiro do que tornar seu programa mais rápido sem essa funcionalidade, vá para a otimização. Caso contrário, prossiga com a funcionalidade. Além disso, programadores experientes focados no desempenho não gastam muito tempo otimizando, apenas escrevem programas rápidos. Pelo menos, eles sabem quais ferramentas usar e o que não fazer para passar anos fazendo otimizações sem sentido (leia micro).
fonte