Preâmbulo:
Algumas objeções foram levantadas nos comentários, e acho que elas derivam em grande parte de um mal-entendido do que queremos dizer quando dizemos "otimização prematura" - então eu queria acrescentar um pouco de esclarecimento sobre isso.
"Não otimizar prematuramente" não significa "escrever código que você sabe que é ruim, porque Knuth diz que você não pode limpá-lo até o final"
Significa "não sacrifique tempo e legibilidade para otimização até que você saiba quais partes do seu programa realmente precisam de ajuda para serem mais rápidas". Como um programa típico passa a maior parte do tempo em alguns gargalos, investir na otimização de "tudo" pode não lhe proporcionar o mesmo aumento de velocidade, pois concentra esse mesmo investimento apenas no código de gargalo.
Isso significa que, em caso de dúvida , devemos:
Prefira código simples de escrever, claro de entender e fácil de modificar para iniciantes
Verifique se é necessária uma otimização adicional (geralmente criando um perfil do programa em execução, embora um comentário abaixo faça anotações em análise matemática - o único risco que existe, você também precisa verificar se sua matemática está correta)
Uma otimização prematura não é :
Decisões arquitetônicas para estruturar seu código de forma que atenda às suas necessidades - escolhendo módulos / responsabilidades / interfaces / sistemas de comunicação apropriados de uma maneira considerada.
Eficiências simples que não levam tempo extra ou dificultam a leitura do código. Coisas como usar digitação forte podem ser eficientes e tornar sua intenção mais clara. O armazenamento em cache de uma referência em vez de procurá-la repetidamente é outro exemplo (desde que o seu caso não exija uma lógica complexa de invalidação de cache - talvez você não precise escrever isso até que você crie o perfil da maneira mais simples primeiro).
Usando o algoritmo certo para o trabalho. A * é mais ideal e mais complexo do que pesquisar exaustivamente um gráfico de busca de caminhos. É também um padrão da indústria. Repetindo o tema, a adesão a métodos testados e comprovados como esse pode facilitar a compreensão do código do que se você fizer algo simples, mas contrário às práticas recomendadas conhecidas. Se você tiver experiência em encontrar gargalos na implementação do recurso X do jogo de uma maneira em um projeto anterior, não precisará acertar o mesmo gargalo novamente neste projeto para saber que é real - você pode e deve reutilizar soluções que funcionaram no passado jogos
Todos esses tipos de otimizações são bem justificáveis e geralmente não seriam rotulados de "prematuros" (a menos que você esteja descendo uma toca de coelho implementando a busca de caminhos de ponta no seu mapa de tabuleiro de xadrez 8x8 ...)
Agora, com isso esclarecido, sobre por que podemos achar essa política útil em jogos especificamente:
Em gamedev, especialmente, a velocidade da iteração é a coisa mais preciosa. Muitas vezes, implementamos e reimplementamos muito mais idéias do que as que acabam sendo fornecidas com o jogo finalizado, tentando "encontrar a diversão".
Se você pode criar um protótipo de um mecânico de maneira direta e talvez um pouco ingênua e testá-lo no dia seguinte, você está em uma posição muito melhor do que se passasse uma semana criando a versão mais ideal primeiro. Especialmente se isso for péssimo e você acabar descartando esse recurso. Fazer isso da maneira mais simples para que você possa testar cedo pode economizar uma tonelada de trabalho desperdiçado, otimizando o código que você não mantém.
O código não otimizado também é geralmente mais fácil de modificar e experimentar diferentes variantes do que o código ajustado para fazer uma coisa precisa de maneira ideal, que tende a ser quebradiça e mais difícil de modificar sem quebrá-lo, introduzir bugs ou diminuir a velocidade. Portanto, manter o código simples e fácil de mudar geralmente vale um pouco da ineficiência do tempo de execução durante a maior parte do desenvolvimento (normalmente desenvolvemos máquinas acima da especificação de destino, para que possamos absorver a sobrecarga e nos concentrar em obter a experiência de destino primeiro) até que bloqueou o que precisamos do recurso e pode otimizar as peças que sabemos agora serem lentas.
Sim, refatorar partes do projeto com atraso no desenvolvimento para otimizar os pontos lentos pode ser difícil. Mas o mesmo acontece com a refatoração repetida ao longo do desenvolvimento, porque as otimizações que você fez no mês passado não são compatíveis com a direção em que o jogo evoluiu desde então, ou estavam consertando algo que acabou não sendo o gargalo real, uma vez que você obtém mais recursos e conteúdo no.
Os jogos são estranhos e experimentais - é difícil prever como um projeto de jogo e suas necessidades tecnológicas evoluirão e onde o desempenho será mais apertado. Na prática, muitas vezes acabamos nos preocupando com as coisas erradas - pesquise nas perguntas de desempenho aqui e você verá um tema comum emergindo dos desenvolvedores sendo distraídos por coisas no papel que provavelmente não são um problema.
Para dar um exemplo dramático: se o seu jogo for vinculado à GPU (não incomum), todo esse tempo gasto com a otimização e o enfoque no trabalho da CPU poderá não trazer benefícios tangíveis. Todas essas horas de desenvolvimento poderiam ter sido gastas implementando e aprimorando os recursos de jogabilidade, para uma melhor experiência do jogador.
No geral, a maior parte do tempo que você gasta trabalhando em um jogo não será gasta no código que acaba sendo o gargalo. Especialmente quando você está trabalhando em um mecanismo existente, o material de loop interno super caro nos sistemas de renderização e física está em grande parte fora de suas mãos. Nesse ponto, seu trabalho nos scripts de jogabilidade é basicamente ficar fora do caminho do mecanismo - desde que você não jogue uma chave lá, então provavelmente sairá bem para a primeira compilação.
Portanto, além de um pouco de higiene e orçamento do código (por exemplo, não procure / construa repetidamente coisas, se você puder reutilizá-las facilmente, mantenha modestas as consultas de localização / física ou as leituras de GPU, etc.), criando o hábito de não exagerar. - otimizar antes que saibamos onde estão os problemas reais para melhorar a produtividade - poupando-nos de perder tempo otimizando as coisas erradas e mantendo nosso código mais simples e fácil de ajustar em geral.