Je programme depuis quelques années et je me suis souvent retrouvé face à un dilemme.
Il y a deux solutions -
- l'une est simple, c'est-à-dire une approche simple, plus facile à comprendre et à maintenir. Cela implique une certaine redondance, un travail supplémentaire (extra IO, extra processing) et n'est donc pas la solution la plus optimale.
- mais d'autres utilisent une approche complexe, difficile à mettre en œuvre, impliquant souvent une interaction entre beaucoup de modules et est une solution efficace en termes de performances.
Quelle solution devrais-je essayer lorsque je n'ai pas de SLA de performance difficile à respecter et même la solution simple peut répondre au SLA de performance? J'ai éprouvé du dédain chez mes collègues développeurs pour une solution simple.
Est-ce une bonne pratique de trouver la solution complexe la plus optimale si votre SLA de performance peut être atteint par une solution simple?
Réponses:
Le simple. Il répond aux spécifications, il est plus facile à comprendre, il est plus facile à entretenir et il est probablement beaucoup moins bogué.
Ce que vous faites en préconisant la solution efficace en termes de performances, c'est d'introduire une généralité spéculative et une optimisation prématurée dans votre code. Ne fais pas ça! Les performances vont à l'encontre de presque toutes les autres «fonctionnalités» de génie logiciel (fiabilité, maintenabilité, lisibilité, testabilité, compréhensibilité, ...). Rechercher les performances lors des tests indique qu'il est vraiment nécessaire de rechercher les performances.
Ne poursuivez pas les performances lorsque les performances n'ont pas d'importance. Même si cela importe, vous ne devez rechercher les performances que dans les domaines où les tests indiquent qu'un goulot d'étranglement des performances existe. Ne laissez pas les problèmes de performances être une excuse pour remplacer
simple_but_slow_method_to_do_X()
par une version plus rapide si cette version simple ne se présente pas comme un goulot d'étranglement.Les performances améliorées sont presque inévitablement gênées par une multitude de problèmes d'odeur de code. Vous en avez mentionné plusieurs dans la question: Une approche complexe, difficile à mettre en œuvre, un couplage plus élevé. Est-ce que cela vaut vraiment la peine d'être traîné?
la source
Réponse courte: préférez les solutions simples aux solutions complexes et souvenez -vous des principes KISS et YAGNI
Étant donné que les exigences initiales du projet et le logiciel ne sont jamais parfaits, ils nécessitent des modifications à mesure que l'application est développée / utilisée. L'approche itérative dans les phases de développement est un très bon moyen de commencer les choses simplement et de l'étendre au besoin. Les solutions les plus simples ont de la flexibilité et sont plus faciles à entretenir.
De plus, essayer d'être intelligent et placer une optimisation supplémentaire lors de la construction de votre application n'est pas une bonne pratique et peut compliquer votre solution de manière excessive. Comme on le sait,
"premature optimization is the root of all evil"
- du livre de Knuthla source
Prenez une leçon de Knuth ici: "Nous devons oublier les petites efficacités, disons environ 97% du temps: l'optimisation prématurée est la racine de tout mal".
Pensez à vos solutions dans cet ordre: d'abord, toujours, l'exactitude. Deuxièmement, améliorez la clarté et la simplicité. Troisièmement, et seulement lorsque vous pouvez démontrer le besoin, l'efficacité.
Ajouter de l'efficacité vous coûtera presque toujours quelque chose d'important, et ne devrait donc être poursuivi que lorsque vous savez que vous en avez besoin.
la source
La simplicité est la condition préalable de la fiabilité . Si vous avez une solution simple qui fonctionne, allez-y certainement! Il est beaucoup plus facile d'optimiser un programme de travail que de faire fonctionner un programme optimisé. N'oubliez pas non plus la loi de Moore : si votre solution simple atteint aujourd'hui les objectifs de performance, elle les écrasera probablement 1 en un an ou deux.
1 Il n'y a aucune garantie, car comme Jimmy Hoffa l'a noté dans son commentaire ci-dessous, la loi de Moore a ses limites.
la source
Optimal est un mot ambigu!
En fin de compte, s'il y a beaucoup de risques à devoir maintenir le complexe, et si le simple est "assez bon", je me tromperais toujours du côté du simple.
Ajoutez à cela le risque que le complexe ne soit pas assez bon, alors KISS est probablement la bonne réponse.
la source
Je préfère le simple. À mon avis, les optimisations prématurées causent autant de problèmes qu'elles en résolvent. Dans de nombreux cas, une bonne conception vous permet de modifier des implémentations données à l'avenir, si elles deviennent des goulots d'étranglement.
Donc en fin de compte - je vais le concevoir aussi flexible que possible, mais ne sacrifierai pas trop la simplicité pour la flexibilité.
la source
Lequel coûte le moins cher?
La plupart du temps, une solution simple légèrement plus lente sera parfaitement acceptable en termes de performances, et la simplicité rend son développement, sa maintenance et son remplacement moins coûteux.
D'un autre côté, la vitesse est parfois très importante, et le gain financier qui résulte de même de petites améliorations de vitesse peut être bien plus important que le coût accru d'une solution plus compliquée. Par exemple, une réduction de 0,01 s sur le temps pour achever une transaction peut rendre un système d'échange de titres beaucoup plus rentable. Une amélioration de 10% de l'efficacité d'un système prenant en charge plusieurs millions d'utilisateurs pourrait signifier une réduction significative des coûts de serveur.
Donc, la question que vous devez vous poser est la suivante: l' utilisation de la solution complexe a-t-elle suffisamment d'impact sur le résultat net pour payer son coût supplémentaire? En fait, vous devriez probablement demander à votre client de décider car il paie les factures et en profite. Une bonne option consiste à opter d'abord pour la solution simple et à proposer la solution la plus complexe en tant qu'amélioration possible. Cela vous permet de faire fonctionner votre système et donne à votre client quelque chose pour commencer les tests, et cette expérience peut éclairer la décision d'implémenter (ou de ne pas implémenter) la solution la plus compliquée.
la source
Lors de l'évaluation de deux approches, l'une étant plus simple mais moins efficace tandis que l'autre étant plus complexe et plus efficace, il faut considérer le problème et le domaine du projet.
Considérons un projet logiciel de plusieurs milliards de dollars pour l'industrie des soins de santé qui prévoit une durée de vie de plus de 15 ans de maintenance et +20 ans d'utilisation. Dans un tel projet, la performance ne sera certainement pas une préoccupation, mais la complexité et la structure du projet peuvent causer des problèmes majeurs pour la maintenance du projet, qui dure au moins 15 ans. La maintenabilité et la simplicité passent avant tout.
Ensuite, considérons un autre exemple. Un moteur de jeu de console qui est censé alimenter les prochains jeux de la société pour les 5+ prochaines années. Parce que les jeux sont des programmes extrêmement limités en ressources, l'efficacité passe avant la maintenabilité dans de nombreux cas. L'écriture de vos propres structures de données et algorithmes très spécifiques pour certaines tâches peut être très importante même si elle va à l'encontre de tout type de "meilleures pratiques" de développement logiciel. Un bon exemple de cela pourrait être la conception orientée données dans laquelle vous stockez vos données dans des tableaux de données similaires, plutôt que dans des objets réels. Cela permet d'augmenter la référence de la localité et, en tant que tel, d'augmenter l'efficacité du cache du processeur. Pas pratique, mais très crucial dans le domaine donné.
la source
C'est toujours une question difficile et je vois les réponses osciller dans un sens, donc je vais jouer le jeu pour l'autre côté, bien que je ne prétende pas que l'une ou l'autre réponse soit correcte, c'est un sujet très doux et au cas par cas.
Une chose à propos d'une solution complexe mais à hautes performances est que vous pouvez toujours simplement documenter les problèmes qui en découlent. Je suis généralement un fan de code auto-documenté, mais je suis aussi un fan de logiciels qui répondent dans un laps de temps qui me donne l'impression que cela ne me ralentit pas. Si vous optez pour la solution complexe mais hautes performances, réfléchissez à ce que vous pouvez faire pour la rendre moins mauvaise:
Enveloppez-le dans une interface, mettez-le dans un assemblage seul, peut-être même un processus à lui tout seul. Faites-le aussi lâchement couplé que possible avec un mur d'abstraction aussi épais que possible pour éviter les fuites . Écrivez de nombreux tests unitaires pour enregistrer les régressions à l'avenir.
Documentez-le dans le code, pensez même à écrire de la vraie documentation. Pensez aux structures de données complexes et à la façon dont elles sont documentées, imaginez essayer de comprendre la mise en œuvre de l'une d'entre elles à partir du code sans un livre de structures de données / article wikipedia pour l'expliquer. Et pourtant, nous acceptons tous que ces structures de données complexes sont en fait de bonnes choses et il est avantageux que quelqu'un les ait mises en œuvre dans nos langues.
N'oubliez pas que nous envoyons tous des messages sur une pile TCP / IP qui est probablement aussi difficile que le code puisse obtenir si l'un d'entre nous le regarde, expressément pour qu'il fonctionne de la manière dont nous en avons tous besoin. Peut-être que votre problème ne nécessite pas ce niveau d'optimisation, peut-être, mais faites attention lorsque vous abordez cette question, comme nous le devons tous de temps en temps: il y a des dragons là-bas.
la source
J'arrive à ce travail dans des domaines où il n'y a pas de SLA de performance. En ce qui concerne les moteurs de rendu hors ligne en infographie, il n'y a pas de "performances satisfaisantes" pour les utilisateurs, car ils dépensent déjà d'énormes sommes d'argent pour répartir l'informatique sur les clouds et rendre les batteries de serveurs, même avec les moteurs de rendu les plus modernes. pour produire des images et des images de qualité production pour des films, par exemple
Mais je dois dire en tant qu'entreprise travaillant dans ce domaine depuis de nombreuses années que toute solution qui dégrade considérablement la maintenabilité en faveur de l'efficacité fonctionne en fait contre les exigences de performance en constante évolution. Parce que si vous ne pouvez pas maintenir efficacement votre solution pendant des années à venir alors que les choses changent sous vos pieds (à la fois en termes de code environnant et de ce que les utilisateurs attendent que les concurrents continuent de se surpasser les uns les autres), alors votre solution travaille déjà vers l'obsolescence et besoin de remplacement en gros.
Je ne vois pas le but ultime de profileurs comme VTune comme un moyen d'accélérer l'exécution de mon code. Leur valeur ultime est de m'assurer que je ne dégrade pas ma productivité pour répondre à des exigences de performance en constante augmentation. Si je dois absolument appliquer une micro-optimisation grossière, le profileur, combiné à son exécution sur des cas d'utilisateurs réels (et non à un cas de test, j'imagine peut- être important), s'assure que j'applique une telle apparence inévitablement grossière optimisations très, très judicieusement uniquement aux meilleurs hotspots qui apparaissent ainsi que de les documenter très soigneusement car je devrai inévitablement les revoir, les maintenir et les modifier et les modifier pour les années à venir si cette solution reste viable.
Et surtout si votre solution optimisée implique plus de couplage, je serais vraiment réticent à l'utiliser. Parmi les mesures les plus précieuses que j'apprécie dans les domaines les plus critiques de la base de code, le découplage (comme pour minimiser la quantité d'informations que quelque chose doit fonctionner, ce qui minimise également la probabilité qu'il nécessite des modifications à moins qu'il n'ait directement besoin de modifications) ), car ces domaines critiques multiplient considérablement les raisons pour lesquelles les choses changent. Ce qui signifie que moins il faut d'informations pour fonctionner, moins il y a de raisons de changer et minimiser les raisons du changement est vraiment une partie énorme de l'amélioration de la productivité dans mes domaines de concentration particuliers parce que les choses vont devoir constamment changer de toute façon (nous deviendra obsolète dans un an sinon),
Pour moi, les solutions les plus grandes et les plus efficaces que j'ai trouvées sont celles où l'efficacité, la maintenabilité et la productivité ne sont pas diamétralement opposées. La quête pour moi est d'essayer de rendre ces concepts aussi harmonieux que possible.
la source