Quando a otimização não é prematura e, portanto, não é má?

75

"A otimização prematura é a raiz de todo o mal" é algo que quase todos nós ouvimos / lemos. O que eu estou curioso é que tipo de otimização não é prematura, ou seja, em todas as fases de desenvolvimento de software (design de alto nível, design detalhado, implementação de alto nível, implementação detalhada, etc.) que extensão de otimização podemos considerar sem passar para o lado negro.

    
por Gaurav 01.01.2011 / 08:10
fonte

13 respostas

112

Quando você está se baseando na experiência? Não é mal. "Toda vez que fizemos X, sofremos um ataque brutal de desempenho. Vamos planejar otimizar ou evitar o X totalmente desta vez."

Quando é relativamente indolor? Não é mal. "Implementar isso como Foo ou Bar levará tanto trabalho quanto, mas, em teoria, Bar deveria ser muito mais eficiente. Vamos barrar isso."

Quando você está evitando algoritmos ruins que escalam terrivelmente? Não é mal. "Nosso líder tecnológico diz que nosso algoritmo de seleção de caminho proposto é executado em tempo fatorial; não tenho certeza do que isso significa, mas ela sugere que comecemos o seppuku, mesmo considerando isso. Vamos considerar outra coisa."

O mal vem de gastar muito tempo e resolver problemas de energia que você não conhece realmente existe. Quando os problemas definitivamente existem, ou quando os psudo-problemas fantasmas podem ser resolvidos de forma barata, o mal vai embora.

Steve314 e Matthieu M. levantar pontos nos comentários que devem ser considerados. Basicamente, algumas variedades de otimizações "indolores" simplesmente não valem a pena porque a atualização de desempenho trivial que elas oferecem não vale a pena a ofuscação de código, elas estão duplicando melhorias que o compilador já está executando, ou ambos. Veja os comentários de alguns bons exemplos de não-aprimoramentos inteligentes demais por meio.

    
por 01.01.2011 / 08:45
fonte
35

O código do aplicativo deve ser tão bom quanto necessário, mas código da biblioteca deve ser o melhor possível, pois você nunca sabe como sua biblioteca será usada. Então, quando você está escrevendo um código de biblioteca, ele precisa ser bom em todos os aspectos, seja em desempenho, robustez ou qualquer outra categoria.

Além disso, você precisa pensar em desempenho quando você cria seu aplicativo e quando você seleciona algoritmos . Se não for projetada para ter um bom desempenho, nenhum grau de hackeria pode torná-la mais produtiva e nenhuma micro-otimização superará um algoritmo superior.

    
por 01.01.2011 / 21:39
fonte
24

what kind of optimization [is] not premature

O tipo que surge como resultado de problemas conhecidos.

    
por 01.01.2011 / 08:34
fonte
17

When is optimization not premature and therefore not evil?

É difícil dizer o que é bem e mal. Quem tem esse direito? Se olharmos para a natureza, parece que estamos programados para a sobrevivência com uma ampla definição de "sobrevivência", que inclui a transmissão de nossos genes para a prole.

Então, eu diria, pelo menos de acordo com nossas funções básicas e programação, que a otimização não é má quando está alinhada com o objetivo da reprodução. Para os caras, há as loiras, morenas, ruivas, muitas adoráveis. Para as garotas, tem caras, e algumas parecem estar bem.

Talvez devêssemos estar otimizando para esse propósito, e lá isso ajuda a usar um profiler. O profiler permitirá que você priorize suas otimizações e tempo de forma mais eficaz, além de fornecer informações detalhadas sobre pontos de acesso e por que eles ocorrem. Isso lhe dará mais tempo livre gasto para a reprodução e sua busca.

    
por 03.01.2016 / 20:19
fonte
15

A cotação completa define quando a otimização é não prematuro:

A good programmer will not be lulled into complacency by such reasoning, he will be wise to look carefully at the critical code; but only after that code has been identified. [emphasis mine]

Você pode identificar o código crítico de várias maneiras: estruturas de dados críticos ou algoritmos (por exemplo, usados intensamente ou o "núcleo" do projeto) podem fornecer grandes otimizações, muitas pequenas otimizações são identificadas através de criadores de perfil e assim por diante.

    
por 14.01.2011 / 00:56
fonte
11

Você deve sempre escolher uma solução "boa o suficiente" em todos os casos com base em suas experiências.

O termo de otimização refere-se a escrever "código mais complexo do que 'bom o suficiente' para torná-lo mais rápido" antes de realmente saber que é necessário, tornando o código mais complexo do que o necessário. Complexidade é o que torna as coisas difíceis, então isso não é uma coisa boa.

Isto significa que você não deve escolher um super complexo "pode classificar arquivos de 100 Gb trocando transparentemente para o disco" rotina de ordenação quando um tipo simples serve, mas você também deve fazer uma boa escolha para o tipo simples em primeiro lugar . Escolher cegamente o Bubble Sort ou "escolher todas as entradas aleatoriamente e ver se elas estão em ordem. Repetir." raramente é bom.

    
por 01.01.2011 / 09:33
fonte
3

Minha regra geral: se você não tem certeza de que precisará da otimização, suponha que não precisa. Mas lembre-se de quando você precisa otimizar. Existem alguns problemas que você pode saber de antemão. Isso geralmente envolve a escolha de bons algoritmos e estruturas de dados. Por exemplo, se você precisar verificar a associação em uma coleção, pode ter certeza de que precisará de algum tipo de estrutura de dados definida.

    
por 01.01.2011 / 21:52
fonte
3

Na minha experiência, na fase de implementação detalhada, a resposta está no perfil do código. É importante saber o que precisa ser mais rápido e o que é aceitavelmente rápido.

Também é importante saber exatamente onde está o gargalo de desempenho - otimizar uma parte do código que leva apenas 5% do tempo total para execução não faz nenhum bem.

Os passos 2 e 3 descrevem a otimização não prematura:

  1. Faça funcionar
  2. Teste. Não é rápido o suficiente? Faça o perfil .
  3. Usando os dados da etapa 2, otimize as seções mais lentas do código.
por 07.01.2011 / 00:28
fonte
3

Não é otimização ao escolher coisas que são difíceis de mudar, por exemplo: plataforma de hardware.

Escolher estruturas de dados é um bom exemplo - fundamental para atender aos requisitos funcionais e não funcionais (desempenho). Não é facilmente alterado e, no entanto, vai impulsionar todo o resto da sua aplicação. Suas estruturas de dados alteram quais algoritmos estão disponíveis, etc.

    
por 15.03.2012 / 14:24
fonte
3

Eu só sei de uma maneira de responder a essa pergunta, e isso é para obter experiência em ajuste de desempenho. Isso significa - escrever programas, e depois de eles serem escritos, encontrar speedups neles e fazer iterativamente. Veja um exemplo.

Aqui está o erro que a maioria das pessoas faz: Eles tentam otimizar o programa antes de realmente executá-lo. Se eles fizeram um curso de programação (de um professor que na verdade não tem muita experiência prática) eles terão óculos grandes e coloridos, e eles vão pensar que é isso que é tudo sobre . É tudo o mesmo problema, otimização prévia. **

Alguém disse: primeiro faça certo, então faça isso rápido. Eles estavam certos.

Mas agora para o kicker: Se você fez isso algumas vezes, você reconhece as coisas bobas que você fez anteriormente que causam problemas de velocidade, então você instintivamente as evita. (Coisas como tornar sua estrutura de classe muito pesada, ficar sobrecarregada com notificações, confundir o tamanho das chamadas de função com seu custo de tempo, a lista continua e continua ...) Você instintivamente evita isso, mas adivinhe o que parece para os menos experientes: otimização prematura!

Então, esses debates bobos continuam e continuam:)

** Outra coisa que eles dizem é que você não precisa se preocupar mais com isso, porque os compiladores são tão bons e as máquinas são tão rápidas hoje em dia. (KIWI - mate com ferro.) Não há hardware exponencial ou aumento de velocidade do sistema (feito por engenheiros muito inteligentes e dedicados) que podem compensar a lentidão exponencial do software (feita por programadores que pensam assim).

    
por 30.09.2015 / 15:46
fonte
2

Quando os requisitos ou o mercado especificamente pedem isso.

Por exemplo, o desempenho é um requisito na maioria dos aplicativos financeiros porque a baixa latência é crucial. Dependendo da natureza do instrumento negociado, a otimização pode ir do uso de algoritmos sem travamento em uma linguagem de alto nível para usar uma linguagem de baixo nível e até mesmo o extremo - implementar algoritmos de correspondência de pedidos no próprio hardware (usando FPGA por exemplo ).

Outro exemplo seria alguns tipos de dispositivos incorporados. Tomemos por exemplo o freio ABS; Em primeiro lugar, há a segurança, quando você bate o intervalo o carro deve desacelerar. Mas também há desempenho, você não quer atrasos quando acerta o intervalo.

    
por 16.06.2015 / 09:24
fonte
0

A maioria das pessoas chamaria a otimização de prematura, se você estiver otimizando algo que não está resultando em uma "falha de hardware" (funciona, mas ainda é inútil) do sistema devido ao desempenho.

Exemplos do mundo real.

  • Se meu tipo de bolha levar 20ms para ser executado, otimize-o para envio rápido de 1 ms não vai melhorar a utilidade geral de forma significativa apesar de ser um aumento de desempenho de 2000%.

  • Se uma página da web leva 20s para carregar e a diminuímos para 1s, isso pode aumentar a utilidade do site de 0 a quase infinito. Basicamente algo que foi quebrado porque era muito lento, é agora útil.

por 15.06.2015 / 21:59
fonte
0

Que tipo de otimização não é prematura?

Uma otimização que corrige um problema de desempenho conhecido com seu aplicativo ou uma otimização que permite que seu aplicativo atenda a critérios de aceitação bem definidos.

Tendo sido identificado, algum tempo deve ser tomado para estabelecer a correção e o benefício de desempenho deve ser medido.

(ou seja, não é - "Eu acho que este pedaço do código parece que poderia ser lento, eu vou mudar o X para usar o Y e isso será mais rápido").

Encontrei muita "otimização" prematura que acabou por tornar o código mais lento - neste caso, estou a considerar prematuro o significado de "não pensado". O desempenho deve ser comparado antes e depois da otimização e apenas o código que realmente melhora o desempenho mantido.

    
por 20.12.2017 / 17:44
fonte