Je pense que c'est difficile d'atteindre tous les trois. Je pense que deux peuvent être réalisables. Par exemple, je pense qu'il est possible d'atteindre efficacité et lisibilité dans certains cas, mais la maintenabilité peut être difficile avec du code micro-réglé. Le plus efficace sur le code de la planète manquent souvent à la fois la maintenabilité et la lisibilité est probablement comme évident pour la plupart, à moins que vous êtes le genre qui peut comprendre la main-SoA vectorisé, multithread Code SIMD Intel écrit avec l' assemblage inline, ou le plus coupe Algorithmes novateurs utilisés dans l'industrie avec des articles mathématiques de 40 pages publiés il y a à peine 2 mois et 12 bibliothèques d'un code pour une structure de données incroyablement complexe.
Micro-efficacité
Une chose que je suggérerais qui pourrait être contraire à l’opinion populaire est que le code algorithmique le plus intelligent est souvent plus difficile à maintenir que l’algorithme simple le plus micro-réglé. Cette idée que les améliorations en matière d’évolutivité rapportent plus sur le code micro-ajusté (ex: schémas d’accès conviviaux pour le cache, multithreading, SIMD, etc.) est quelque chose que je contesterais, au moins après avoir travaillé dans un secteur extrêmement complexe. structures de données et algorithmes (l'industrie des effets visuels), en particulier dans des domaines tels que le traitement de maillage, parce que le bang est énorme, mais que le coût est extrêmement coûteux lorsque vous introduisez de nouveaux algorithmes et structures de données dont personne n'a jamais entendu parler depuis qu'ils sont de marque Nouveau. De plus, je '
Donc, cette idée que les optimisations algorithmiques ont toujours préséance sur, disons, les optimisations liées aux modèles d'accès à la mémoire est toujours quelque chose avec lequel je n'étais pas tout à fait d'accord. Bien sûr, si vous utilisez une sorte de bulle, aucune micro-optimisation ne peut vous aider… mais dans des limites raisonnables, je ne pense pas que ce soit toujours aussi net. Et on peut soutenir que les optimisations algorithmiques sont plus difficiles à maintenir que les micro-optimisations. Je trouve qu'il est beaucoup plus facile de maintenir, par exemple, Embree d'Intel, qui utilise un algorithme BVH classique et simple et en résout simplement le foutre que le code OpenVDB de Dreamwork pour des méthodes de pointe d'accélération algorithmique de la simulation fluide. Donc, au moins dans mon secteur d'activité, j'aimerais voir davantage de personnes familiarisées avec la micro-optimisation de l'architecture informatique, comme le faisait Intel lorsqu'elles sont entrées en scène, au lieu de proposer des milliers et des milliers de nouveaux algorithmes et structures de données. Avec des micro-optimisations efficaces, les utilisateurs pourraient potentiellement trouver de moins en moins de raisons d'inventer de nouveaux algorithmes.
Auparavant, je travaillais dans une base de code héritée, où presque chaque opération utilisateur possédait sa propre structure de données et son algorithme (ajoutant ainsi des centaines de structures de données exotiques). Et la plupart d’entre eux avaient des caractéristiques de performance très asymétriques, s’appliquant très étroitement. Cela aurait été tellement plus facile si le système pouvait s'articuler autour d'une vingtaine de structures de données plus largement applicables, et je pense que cela aurait pu être le cas si elles avaient été optimisées au niveau micro. Je parle de ce cas parce que la micro-optimisation peut potentiellement améliorer considérablement la maintenabilité dans un tel cas si cela signifie la différence entre des centaines de structures de données micro-pessimisées qui ne peuvent même pas être utilisées en toute sécurité à des fins strictes en lecture seule, ce qui implique des erreurs de cache en mémoire. droit vs.
Langages fonctionnels
Entre-temps, certains des codes les plus faciles à gérer que j'ai rencontrés étaient assez efficaces, mais extrêmement difficiles à lire, car ils étaient écrits dans des langages fonctionnels. En général, la lisibilité et la maintenabilité sont des idées contradictoires à mon avis.
Il est très difficile de rendre le code lisible, maintenable et efficace en même temps. En règle générale, vous devez faire un compromis sur l'un de ces trois, voire deux, comme compromettre la lisibilité pour la maintenabilité ou compromettre la maintenabilité pour l'efficacité. C’est généralement la facilité de maintenance qui en souffre lorsque vous recherchez beaucoup les deux autres.
Lisibilité contre maintenabilité
Maintenant, comme je l’ai dit, la lisibilité et la maintenabilité ne sont pas des concepts harmonieux. Après tout, le plus code lisible pour la plupart d' entre nous mortels cartes très intuitivement à des modèles pensée humaine, et les modèles de pensées humaines sont intrinsèquement sujettes à l' erreur: " . Dans ce cas, le faire si cela se produit, le faire faire autrement cette Oops.. J'ai oublié quelque chose! Si ces systèmes interagissent les uns avec les autres, cela devrait se produire pour que ce système puisse le faire ... oh, attendez, qu'en est-il de ce système lorsque cet événement est déclenché?"J'avais oublié la citation exacte, mais quelqu'un a dit un jour que si Rome était construite comme un logiciel, il suffirait qu'un oiseau se pose sur un mur pour le faire tomber. C'est le cas de la plupart des logiciels. C'est plus fragile que nous nous soucions souvent de Quelques lignes de code apparemment inoffensif ici et là pourraient bien nous permettre de revenir sur notre conception, et les langages de haut niveau visant à être aussi lisibles que possible ne font pas exception à de telles erreurs de conception. .
Les langages fonctionnels purs sont à peu près aussi invulnérables que possible (pas même invulnérables, mais relativement plus proches que la plupart des autres). Et c'est en partie parce qu'ils ne correspondent pas intuitivement à la pensée humaine. Ils ne sont pas lisibles. Ils nous imposent des schémas de pensée qui nous obligent à résoudre des problèmes avec le moins de cas spéciaux possible en utilisant le minimum de connaissances possible et sans provoquer d'effets secondaires. Ils sont extrêmement orthogonaux, ils permettent souvent de changer sans cesse le code, si surprenant que nous devons repenser la conception sur une planche à dessin, au point de changer d’avis sur la conception globale, sans avoir à tout réécrire. Cela ne semble pas être plus facile à gérer que ça ... mais le code est toujours très difficile à lire,