36 pontos por GN⁺ 2026-03-19 | 1 comentários | Compartilhar no WhatsApp
  • Regra 1: não é possível prever onde um programa vai gastar tempo. Gargalos surgem em lugares inesperados, então não tente melhorar a velocidade até que fique comprovado que ali está o gargalo
  • Regra 2: medir vem primeiro. Ajustes de desempenho só devem ser feitos depois da medição, e otimização só deve ser considerada quando uma parte do código domina o todo
  • Regra 3: algoritmos complexos são lentos para n pequeno. Algoritmos complexos têm constantes grandes; a menos que n frequentemente cresça muito, use métodos simples. Mesmo que n cresça, aplique primeiro a regra 2
  • Regra 4: algoritmos complexos têm mais bugs e são difíceis de implementar. É desejável usar algoritmos simples e estruturas de dados simples
  • Regra 5: dados são o núcleo. Se você escolher a estrutura de dados correta e organizá-la bem, o algoritmo quase se revela por si só. O centro da programação não é o algoritmo, mas a estrutura de dados

Filosofia e citações relacionadas

  • As regras 1 e 2 têm o mesmo sentido da máxima de Tony Hoare: “otimização prematura é a raiz de todo mal”
  • Ken Thompson reinterpretou as regras 3 e 4 como “na dúvida, use o método simples (Brute Force)”
  • As regras 3 e 4 são exemplos da filosofia de design KISS (Keep It Simple, Stupid)
  • A regra 5 já havia sido mencionada por Fred Brooks em The Mythical Man-Month e
    costuma ser resumida como “escrever código simples usando objetos inteligentes”

1 comentários

 
GN⁺ 2026-03-19
Comentários do Hacker News
  • Isso lembrou a palestra do Jonathan Blow
    Ele abordou isso pela ótica da produtividade. No início do desenvolvimento de Braid, implementou quase tudo com arrays simples e só mudava quando surgia um gargalo
    Foi marcante a frase: “Mais importante do que velocidade ou memória é o tempo de vida necessário para implementar um programa”

    • Jogos processam repetidamente um grande número de objetos semelhantes a mais de 60 quadros por segundo, então uma estrutura baseada em arrays simples é um padrão razoável
    • No desenvolvimento de jogos, é preciso renderizar um frame em 16 ms, então tabelas de tamanho fixo e busca linear são padrões comuns. É uma escolha estrutural para evitar a imprevisibilidade da alocação dinâmica
    • Essa visão também vale para desenvolvimento geral fora de jogos. Todos trabalhamos sob prazos e restrições de custo, então o próprio tempo de engenharia é um custo
    • Ainda assim, é preciso cuidado ao estender diretamente as lições dos jogos para a programação em geral. Jogos são centrados mais em código de propósito específico do que em reutilização, enquanto software geral é centrado em dados
    • No meu caso, sou do tipo que começa com um hash map em vez de array
  • Se você leva a sério a Rule 1, as Rules 3 a 5 vêm naturalmente
    Se você aceita a premissa de que não dá para prever gargalos, então escrever código simples e medir vira a única estratégia racional
    Na prática, o fracasso mais comum não é otimização prematura, e sim abstração prematura. Criamos camadas complexas por uma flexibilidade que não era necessária, e isso acaba aumentando o custo de manutenção

    • Costumo citar muito no time a frase: “A abstração deve surgir naturalmente, não ser projetada de antemão”
    • A abstração prematura desperdiça tempo de desenvolvedor, aumenta a dívida técnica e eleva a chance de bugs. Muitas vezes nasce sob o pretexto de “se preparar para problemas futuros”
    • Como texto relacionado, vale consultar o artigo de Philip Wadler
    • Eu valorizo mais legibilidade e manutenibilidade do que desempenho. Por isso, para mim, a Rule 4 é a base, e a Rule 1 é consequência dela
    • Já passei por um caso em que arquivos de configuração complexos foram separados em excesso. No fim, 8 arquivos YAML simples já bastavam
  • Tive a experiência, nos anos 90, de precisar implementar uma busca em dataset às 2 da manhã
    Eu estava cansado, então fiz uma busca linear para corrigir depois, mas na prática a diferença foi de apenas 6 segundos em um teste de 4 horas
    No fim eu até alterei, mas não houve diferença significativa

    • Para n pequeno, a busca linear pode até ser mais rápida
    • Mas algoritmos O(n²) têm o risco de “entrarem em produção e depois explodirem em operação
  • Concordo totalmente com a Rule 5
    Quanto mais difícil o problema, mais ele costuma ser resolvido por meio de melhorias iterativas na estrutura de dados e na API. Quando a estrutura fica bem definida, o fluxo de controle se torna natural
    LLMs são fracos nesse tipo de raciocínio estrutural. Eles sugerem bem fluxos de controle complexos, mas não sabem projetar bem estruturas de dados combináveis

    • Pela minha experiência, a Rule 5 é na prática a Rule 1. Existe a frase: “Se você me mostrar o código eu fico confuso, mas se me mostrar o schema do banco de dados tudo fica claro”
    • Em serviços distribuídos, a Rule 5 costuma ser ignorada com frequência. Em vez de dividir em várias chamadas HTTP e de banco, uma estrutura que resolva com uma única chamada é mais eficiente
  • Venho de engenharia elétrica (E.E.) e, graças à Rule 3, não tive grandes problemas no início da carreira
    Mas depois, ao migrar para sistemas de grande escala, n cresceu e a complexidade passou a importar de verdade
    O “big iron” da época a que Rob Pike se referia era parecido com o ambiente embarcado de hoje

    • Discordo em parte da Rule 3. Em entradas pequenas isso não importa, mas em entradas grandes o desempenho assintótico importa.
      Se dois algoritmos têm dificuldade de implementação parecida, eu escolho o mais rápido para entradas grandes
      Texto relacionado: Less Than Quadratic
    • O significado de “fancy” precisa ser interpretado de acordo com o domínio do problema. Se n é pequeno, uma abordagem simples é melhor; se n é grande, algoritmos mais sofisticados são indispensáveis
      Muitas vezes as pessoas escolhem uma abordagem O(n²) simples demais e acabam vendo tudo explodir em produção
    • Meu pai já gostava de usar lookup tables desde a era do Fortran. É uma forma clássica de otimização para reduzir cálculos repetidos
  • Acho que as regras do Pike são melhores do que os aforismos tradicionais
    Frases como “otimização prematura é a raiz de todo mal” perdem o contexto e são fáceis de interpretar mal
    A versão do Pike é clara e difícil de usar de forma errada
    Havia uma formulação antiga de que “a Rule 5 se resume a ‘deixe código burro usar objetos inteligentes’”,
    mas na era orientada a objetos isso acabou se deturpando em uma crença errada de esconder a complexidade

    • É importante manter os elos de continuidade do pensamento histórico
    • A expressão “clickbait mental dos aforismos clássicos” soa como uma metáfora espirituosa
  • Depois de mais de 10 anos mantendo a mesma base de código, internalizei completamente as regras de Pike
    Seguir os princípios KISS/DRY e manter tecnologias comprovadas em vez de modismos foi mais estável no longo prazo
    Na prática, o documento de princípios de desenvolvimento do nosso time é quase idêntico às regras de Pike

  • No começo dos anos 1990, na era do C++, troquei uma lista duplamente encadeada por realocação simples de array
    Não só os bugs desapareceram, como ainda ficou mais rápido.
    Aprendi que fazer operações caras com menos frequência é uma boa estratégia

  • É interessante comparar a regra “não faça tuning sem medir” com Latency Numbers Every Programmer Should Know, do Jeff Dean
    Dean diz que é possível prever desempenho com conhecimento prévio
    No fim, as duas posições podem ser conciliadas — na fase de design, você escolhe uma estrutura que intuitivamente seja rápida e, depois da implementação, faz o ajuste fino com base em medições

    • Código realmente rápido usa as duas abordagens. Na fase de design, considera a eficiência de cache; depois, elimina gargalos com profiling
    • Números de latência só mostram o limite teórico do algoritmo; o desempenho real varia conforme a implementação e o ambiente de execução
    • O que a “otimização prematura” proíbe é o tuning local no nível de gambiarra. Considerar velocidade no design geral é algo natural
  • As Rules 1 e 2 só são absolutas quando se está lidando com um problema novo
    Quando você constrói sistemas repetidamente no mesmo domínio, consegue prever gargalos com antecedência
    Um desenvolvedor experiente pode ter uma noção aproximada de desempenho já antes do design

    • Eu também acertei com precisão os gargalos na maioria dos casos. Muitas vezes mudei de abordagem com base em testes prévios de desempenho
    • Mas, pela minha experiência de 30 anos, a intuição de que haverá gargalo costuma estar certa, porém o local exato e o momento em que ele aparece são imprevisíveis
    • Também havia a piada “o que o Rob Pike sabe?”, mas ele é a pessoa por trás do Unix e do Go. Há motivos para suas regras existirem