Eu posso ser tendencioso trabalhando em áreas muito críticas de desempenho, como processamento de imagem e rastreamento de raios, mas ainda assim diria para otimizar "o mais tarde possível" . Não importa quão críticos sejam o desempenho de seus requisitos, sempre há muito mais informações e clareza em retrospectiva, depois da avaliação, do que antes, o que significa que mesmo as otimizações mais eficazes são normalmente aplicadas mais tarde após o ganho de tal conhecimento.
Casos peculiares
Mas, às vezes, "o mais tarde possível" ainda é bem cedo em alguns casos peculiares. Se estivermos falando de renderizadores offline, por exemplo, as estruturas e técnicas de dados que você usa para obter desempenho realmente se infiltram no design final do usuário. Isso pode parecer nojento, mas o campo é tão avançado e tão crítico quanto ao desempenho que os usuários aceitam controles finais do usuário específicos para as técnicas de otimização aplicáveis a um determinado traçador de raios (ex: cache de irradiância ou mapeamento de fótons), já que alguns deles são usados até horas de espera para que uma imagem seja renderizada, e outros são usados para gastar enormes somas de dinheiro para alugar ou possuir uma fazenda de renderização com máquinas dedicadas à renderização. Há uma enorme redução de tempo e dinheiro para esses usuários, se um renderizador offline competitivo puder oferecer uma redução não trivial no tempo gasto na renderização. Esse é um tipo de área em que uma redução de 5% no tempo realmente excita os usuários.
Em casos tão peculiares, você não pode escolher apenas uma técnica de renderização, querendo ou não, e esperá-la otimizá-la mais tarde, pois todo o design, incluindo o design do usuário, gira em torno das estruturas de dados e algoritmos que você usa. Você não pode necessariamente ir apenas com o que funcionou bem para outras pessoas, pois aqui, você, como indivíduo, e seus pontos fortes e fracos, são muito importantes para fornecer uma solução competitiva. A mentalidade e a sensibilidade do desenvolvedor principal por trás de Arnold são diferentes daqueles que trabalham no VRay que usaram uma abordagem muito diferente; eles não podem necessariamente trocar de lugar / técnica e fazer o melhor trabalho (mesmo sendo os dois líderes industriais). Você precisa experimentar e fazer protótipos e referências e encontrar o que deseja. você é particularmente bom em fazer, dada a infinita variedade de técnicas de ponta disponíveis, se você espera lançar algo competitivo que realmente venderá. Portanto, nesse caso peculiar, as preocupações com o desempenho avançam para a frente como talvez a preocupação mais importante antes mesmo de iniciar o desenvolvimento.
Ainda assim, isso não é necessariamente uma violação da otimização "o mais tarde possível" , é apenas "o mais tarde possível" é bastante cedo nesses casos extremos e peculiares. Descobrir quando e também o que não precisa de preocupações tão precoces de desempenho, se é que alguma vez é, provavelmente é o principal desafio para o desenvolvedor. O que não otimizar pode ser uma das coisas mais valiosas para aprender e continuar aprendendo na carreira de um desenvolvedor, já que não há falta de desenvolvedores ingênuos que desejam otimizar tudo (e, infelizmente, até alguns veteranos que conseguiram, de alguma forma, manter seu emprego em apesar de sua contra-produtividade).
O mais tarde possível
Talvez a parte mais difícil seja tentar entender o que isso significa. Ainda estou aprendendo e programando há quase três décadas. Mas especialmente agora na minha terceira década, estou começando a perceber que não é tão difícil. Não é ciência do foguete, se você se concentrar mais no design do que na implementação. Quanto mais seus projetos deixarem espaço para otimizações apropriadas posteriormente, sem alterações no projeto, mais tarde você poderá otimizar. E quanto mais produtividade ganhei buscando projetos que me proporcionassem esse espaço para respirar.
Design que oferece espaço para otimizar mais tarde
Na verdade, esses tipos de projetos não são tão difíceis de conseguir na maioria dos casos, se podemos aplicar algum "bom senso". Como uma história pessoal, gosto de artes visuais como hobby (acho que ajuda um pouco a programar software para artistas sendo um pouco eu para entender suas necessidades e falar sua língua), e passei algum tempo no início dos anos 2000 usando applets Oekaki on-line como uma maneira rápida de rabiscar, compartilhar meu trabalho e me conectar com outros artistas.
Em particular, meu site e applet favorito estavam repletos de falhas de desempenho (qualquer tamanho de pincel não trivial seria lento para rastrear), mas tinha uma comunidade muito boa. Para solucionar os problemas de desempenho, usei pequenos pincéis de 1 ou 2 pixels e escrevi meu trabalho da seguinte maneira:
Enquanto isso, continuava dando sugestões ao autor do software para melhorar o desempenho, e ele percebeu que minhas sugestões eram de natureza particularmente técnica, falando sobre otimizações de memória e algoritmos e assim por diante. Então ele realmente perguntou se eu era um programador e eu disse que sim e ele me convidou para trabalhar no código fonte.
Então, olhei o código-fonte, executei-o, criei um perfil e, para meu horror, ele projetou o software em torno do conceito de uma "interface abstrata de pixel", como IPixel
, que acabou sendo a causa raiz dos principais hotspots para tudo com dinâmica alocações e envio para cada pixel de cada imagem. No entanto, não havia uma maneira prática de otimizar isso sem reconsiderar todo o design do software, porque o design o aprisionara em um canto em que não há muito além das micro-otimizações mais triviais quando nossas abstrações estão trabalhando no nível granular de um único pixel abstrato e tudo depende desse pixel abstrato.
Eu acho que isso é uma violação do "senso comum", mas obviamente não era um senso comum para o desenvolvedor. Mas é como não abstrair as coisas em um nível tão granular, onde até os casos de uso mais básicos serão instanciados aos milhões, como pixels, partículas ou pequenas unidades em uma simulação de exército gigantesca. Favorecer IImage
(você pode lidar com todos os formatos de imagem / pixel necessários nesse nível agregado mais volumoso) ou IParticleSystem
para IPixel
or IParticle
e, em seguida, você pode colocar as implementações mais básicas, de gravação rápida e de fácil compreensão por trás dessas interfaces e tenha todo o espaço para respirar que você precisará otimizar mais tarde, sem reconsiderar todo o design do software.
E esse é o objetivo que vejo hoje em dia. Excluindo os casos peculiares, como os renderizadores off-line acima, projete com espaço suficiente para otimizar o mais tarde possível, com o máximo de informações retrospectivas possível (incluindo medições) e aplique as otimizações necessárias o mais tarde possível.
É claro que não estou necessariamente sugerindo começar a usar algoritmos de complexidade quadrática em entradas que facilmente atingem um tamanho não trivial em casos comuns de usuários finais. Quem faz isso afinal? Mas nem acho que isso seja tão importante se a implementação for fácil de trocar mais tarde. Isso ainda não é um erro grave se você não precisar reconsiderar nenhum design.