Eu acho que é difícil conseguir todos os três. Eu acho que dois é possível. Por exemplo, acho que é possível obter eficiência e legibilidade em alguns casos, mas a manutenção pode ser difícil com o código micro-ajustado. O código mais eficiente do planeta geralmente não têm tanto de manutenção e legibilidade como é provavelmente óbvio para a maioria, a menos que você é o tipo que pode compreender a mão SoA-vetorizado, multithreaded código SIMD que a Intel escreve com inline montagem, ou o mais corte algoritmos de borda usados no setor com artigos matemáticos de 40 páginas publicados há apenas 2 meses e 12 bibliotecas no valor de código para uma estrutura de dados incrivelmente complexa.
Microeficiência
Uma coisa que eu sugiro que possa ser contrária à opinião popular é que o código algorítmico mais inteligente é geralmente mais difícil de manter do que o algoritmo direto mais micro-ajustado. Essa ideia de que as melhorias de escalabilidade rendem mais dinheiro do que o código micro-ajustado (por exemplo: padrões de acesso amigáveis ao cache, multithreading, SIMD etc.) é algo que eu desafiaria, pelo menos por ter trabalhado em um setor cheio de recursos extremamente complexos. estruturas e algoritmos de dados (a indústria de efeitos visuais), especialmente em áreas como processamento de malha, porque o estrondo pode ser grande, mas o dinheiro é extremamente caro quando você introduz novos algoritmos e estruturas de dados que ninguém nunca ouviu falar, uma vez que é marca Novo. Além disso, eu
Portanto, essa idéia de que otimizações algorítmicas sempre superam, digamos, otimizações relacionadas a padrões de acesso à memória é sempre algo que eu não concordo totalmente. É claro que se você estiver usando um tipo de bolha, nenhuma micro-otimização pode ajudá-lo lá ... mas dentro da razão, eu não acho que seja sempre tão clara. E, sem dúvida, as otimizações algorítmicas são mais difíceis de manter do que as micro otimizações. Eu acho muito mais fácil manter, digamos, o Embree da Intel, que pega um algoritmo BVH clássico e direto e apenas ajusta a porcaria do que o código OpenVDB da Dreamwork para formas avançadas de acelerar algoritmos a simulação de fluidos. Então, no meu setor, pelo menos, eu gostaria de ver mais pessoas familiarizadas com a arquitetura de computadores otimizando mais, como a Intel fez quando entrou em cena, em vez de criar milhares e milhares de novos algoritmos e estruturas de dados. Com micro otimizações eficazes, as pessoas podem encontrar cada vez menos razões para inventar novos algoritmos.
Eu trabalhei em uma base de código legada antes em que quase todas as operações de usuário tinham sua própria estrutura de dados e algoritmo por trás (adicionando centenas de estruturas de dados exóticas). E a maioria deles tinha características de desempenho muito distorcidas, sendo muito restrita. Teria sido muito mais fácil se o sistema pudesse girar em torno de algumas dúzias de estruturas de dados mais amplamente aplicáveis, e acho que poderia ter sido o caso se elas fossem micro-otimizadas muito melhor. Mencionei este caso porque a micro-otimização pode potencialmente melhorar a capacidade de manutenção tremendamente nesse caso, se isso significa a diferença entre centenas de estruturas de dados micro-pessimizadas que nem sequer podem ser usadas com segurança para finalidades restritas de leitura que envolvem falhas de cache deixadas e certo vs.
Idiomas funcionais
Enquanto isso, alguns dos códigos mais sustentáveis que eu já encontrei foram razoavelmente eficientes, mas extremamente difíceis de ler, pois foram escritos em linguagens funcionais. Em geral, a legibilidade e a uber manutenibilidade são idéias conflitantes na minha opinião.
É realmente difícil tornar o código legível, sustentável e eficiente ao mesmo tempo. Normalmente, você precisa comprometer um pouco um desses três, se não dois, como comprometer a legibilidade para manutenção ou comprometer a manutenção para obter eficiência. Geralmente é a manutenção que sofre quando você procura muitos dos outros dois.
Legibilidade vs. Manutenção
Agora, como dito, acredito que legibilidade e manutenção não são conceitos harmoniosos. Afinal, o código mais legível para a maioria de nós, os mortais, mapeia de maneira muito intuitiva os padrões de pensamento humanos, e os padrões de pensamentos humanos são inerentemente propensos a erros: " Se isso acontecer, faça isso. Se isso acontecer, faça isso. Caso contrário, faça isso. , Esqueci uma coisa! Se esses sistemas interagem entre si, isso deve acontecer para que esse sistema possa fazer isso ... oh espere, e o sistema quando esse evento é acionado?"Esqueci a citação exata, mas alguém disse uma vez que se Roma fosse construída como software, seria necessário um pouso de pássaro em uma parede para derrubá-la. É o caso da maioria dos softwares. É mais frágil do que costumamos gostar. Algumas linhas de código aparentemente inócuo aqui e ali podem parar a ponto de nos fazer reconsiderar todo o design, e linguagens de alto nível que visam ser o mais legíveis possível não são exceções a esses erros de design humano .
As linguagens funcionais puras são quase tão invulneráveis quanto se pode viabilizar (nem mesmo perto de invulneráveis, mas relativamente muito mais próximas do que a maioria). E isso é parcialmente porque eles não mapeiam intuitivamente o pensamento humano. Eles não são legíveis. Eles nos impõem padrões de pensamento que nos levam a resolver problemas com o mínimo de casos especiais possível, usando a quantidade mínima de conhecimento possível e sem causar efeitos colaterais. Eles são extremamente ortogonais, permitem que o código seja frequentemente alterado e alterado sem surpresas tão épicas que precisamos repensar o design em uma prancheta, até ao ponto de mudar de idéia sobre o design geral, sem reescrever tudo. Não parece mais fácil manter isso do que isso ... mas o código ainda é muito difícil de ler,