J'ai rencontré beaucoup de gens qui sont dogmatiquement contre tout ce qui peut être considéré comme une "optimisation" dans le sens général du terme en anglais, et ils citent très souvent mot pour mot la citation (partielle) "l'optimisation prématurée est la racine de tout mal" comme justification de leur position, ce qui implique qu'ils interprètent tout ce dont je parle comme une "optimisation prématurée". Cependant, ces vues sont parfois tellement ridiculement ancrées qu'elles rejettent à peu près tout type d'écart algorithmique ou de structure de données de la mise en œuvre la plus pure "naïve" ... ou du moins tout écart par rapport à la façon dont ils ont fait les choses auparavant.Comment peut-on approcher des gens comme celui-ci de manière à les faire "rouvrir les oreilles" après avoir cessé d'entendre parler de "performances" ou "d'optimisation"? Comment puis-je discuter d'un sujet de conception / implémentation qui a un impact sur les performances sans que les gens pensent immédiatement: "Ce gars veut passer deux semaines sur dix lignes de code?"
Maintenant, la position de savoir si "toute optimisation est prématurée et donc mauvaise" a déjà été abordée ici ainsi que dans d'autres coins du Web , et il a déjà été discuté comment reconnaître quand l'optimisation est prématurée et donc mauvaise , mais malheureusement, il y a encore des gens dans le monde réel qui ne sont pas aussi ouverts aux défis de leur foi en l'Anti-Optimisation.
Tentatives précédentes
À quelques reprises, j'ai essayé de fournir le devis complet de Donald Knuth afin d'expliquer que "l'optimisation prématurée est mauvaise" ↛ "toute optimisation est mauvaise":
Il faut oublier les petites efficacités, disons environ 97% du temps: l'optimisation prématurée est à l'origine de tout mal. Pourtant, nous ne devons pas laisser passer nos opportunités dans ces 3% critiques.
Cependant, lors de la fourniture de la totalité du devis, ces personnes deviennent parfois plus convaincues que ce que je fais est Premature Optimization ™ et creusent et refusent d'écouter. C'est presque comme si le mot "optimisation" leur faisait peur: à quelques reprises, j'ai été en mesure de proposer des modifications de code améliorant les performances sans qu'elles soient rejetées en évitant simplement d'utiliser le mot "optimiz (e | ation)" ( et "performance" également - ce mot fait aussi peur) et utilise plutôt une expression comme "architecture alternative" ou "implémentation améliorée". Pour cette raison, il semble vraiment que ce soit vraiment du dogmatisme et non pas en fait qu'ils évaluent ce que je dis de manière critique et puis le rejettent comme non nécessaire et / ou trop coûteux.
la source
Réponses:
Il semble que vous recherchiez des raccourcis pour ne pas essayer d'abord la "mise en œuvre la plus pure naïve", et implémentez directement une "solution plus sophistiquée car vous savez à l'avance que la mise en œuvre naïve ne le fera pas". Malheureusement, cela fonctionnera rarement - lorsque vous n'avez pas de faits concrets ou d' arguments techniques pour prouver que la mise en œuvre naïve est ou sera trop lente, vous avez très probablement tort, et ce que vous faites est une optimisation prématurée. Et essayer de discuter avec Knuth est l'opposé d'avoir un fait dur.
D'après mon expérience, vous devrez soit mordre la balle et essayer d'abord la «mise en œuvre naïve» (et vous serez probablement étonné de voir combien de fois cela est assez rapide), ou vous ferez au moins une estimation approximative du temps d'exécution, comme:
"L'implémentation naïve sera O (n³), et n est supérieur à 100 000; cela fonctionnera quelques jours, tandis que l'implémentation pas si naïve fonctionnera dans O (n), ce qui ne prendra que quelques minutes" .
Ce n'est qu'avec ces arguments à portée de main que vous pouvez être sûr que votre optimisation n'est pas prématurée.
Il n'y a qu'une seule exception à mon humble avis : lorsque la solution la plus rapide est également la plus simple et la plus propre, vous devez utiliser la solution la plus rapide dès le départ. L'exemple standard est celui d'utiliser un dictionnaire au lieu d'une liste pour éviter le code de boucle inutile pour les recherches, ou l'utilisation d'une bonne requête SQL qui vous donne exactement l'enregistrement de résultat dont vous avez besoin, au lieu d'un grand ensemble de résultats qui doit être filtré ensuite dans le code. Si vous avez un tel cas, ne discutez pas des performances- la performance pourrait être un avantage supplémentaire, mais probablement non pertinent, et lorsque vous le mentionnez, les gens pourraient être tentés d'utiliser Knuth contre vous. Discutez de la lisibilité, du code plus court, du code plus propre, de la maintenabilité - pas besoin de "masquer" quoi que ce soit ici, mais parce que ceux-ci (et seulement ceux-là) sont les bons arguments ici.
D'après mon expérience, ce dernier cas est rare - le cas le plus typique est que l'on peut d'abord implémenter une solution simple et naïve qui est mieux compréhensible et moins sujette aux erreurs qu'une solution plus compliquée, mais probablement plus rapide.
Et bien sûr, vous devez connaître suffisamment les exigences et le cas d'utilisation pour savoir quelles performances sont acceptables et quand les choses deviennent "trop lentes" aux yeux de vos utilisateurs. Dans un monde idéal, vous obtiendriez une spécification de performance formelle de votre client, mais dans les projets du monde réel, la performance requise est souvent une zone grise, quelque chose que vos utilisateurs ne vous diront que lorsqu'ils remarqueront que le programme se comporte "trop lentement" en production. Et souvent, c'est le seul moyen efficace de savoir quand quelque chose est trop lent - les commentaires des utilisateurs, et puis vous n'avez pas besoin de citer Knuth pour convaincre vos coéquipiers que leur "implémentation naïve" n'était pas suffisante.
la source
Demandez-vous ceci:
Ce sont des raisons d'optimiser. Donc, si les gens sont opposés, montrez-leur simplement les spécifications et revenez-y et expliquez que nous devons optimiser car nous ne respectons pas les spécifications. En dehors de cela, on aurait du mal à convaincre les autres que l'optimisation est nécessaire.
Je pense que le point principal de la citation est, si vous n'avez pas de problème, n'effectuez pas d'optimisation inutile car le temps et l'énergie pourraient être dépensés ailleurs. D'un point de vue commercial, cela est parfaitement logique.
Secondaire, pour ceux qui craignent l'optimisation, sauvegardez toujours les résultats de performance avec des métriques. Combien plus rapide est le code? Dans quelle mesure les performances se sont-elles améliorées par rapport à la précédente? Si l'on passait seulement deux semaines à améliorer le code de 2% par rapport à la version précédente, si j'étais ton patron, je ne serais pas content. Ces deux semaines auraient pu être consacrées à la mise en œuvre d'une nouvelle fonctionnalité qui pourrait attirer plus de clients et faire plus d'argent.
Enfin, la plupart des logiciels n'ont pas besoin d'être hautement optimisés. Ce n'est que dans quelques industries spécialisées que la vitesse est vraiment importante. Ainsi, la plupart du temps, on peut utiliser à bon escient les bibliothèques et les cadres préexistants.
la source
Commencez par des principes communs qui s'appuient sur l'orientation stratégique de votre groupe.
Mes principes:
Mes principes personnels sur l'écriture de code sont d'abord de viser l'exactitude de mon programme, puis de le profiler et de déterminer s'il a besoin d'être optimisé. Je profile mon code moi-même parce que d'autres programmeurs sont des consommateurs potentiels de mon code - et ils ne l'utiliseront pas s'il est lent - donc pour mon code, la vitesse est une fonctionnalité.
Si vos consommateurs sont des clients, vos clients vous diront si vous avez besoin d'un code plus rapide.
Cependant, il existe des choix de code connus et manifestement meilleurs que l'on peut faire. Je préférerais le faire directement dans mon premier projet pour plusieurs raisons:
En supposant que le besoin d'optimisation est correct
En supposant que c'est une partie vraiment importante de votre code qui nécessite une optimisation, vous pouvez raconter la parabole de Schlemiel le peintre , ou souligner le reste de la citation:
Peser les coûts d'une complexité supplémentaire
Parfois, il y a un coût réel en termes de maintenabilité de la complexité supplémentaire. Dans ce cas, vous pouvez conserver l'implémentation secondaire dans une fonction ou une sous-classe différente et lui appliquer les mêmes unités de test afin qu'il n'y ait aucun doute qu'elle est correcte. Plus tard, si vous profilez votre code et trouvez l'implémentation naïve comme un goulot d'étranglement, vous pouvez basculer dans votre code optimisé et améliorer votre programme de manière démontrable.
Direction
Parfois, le problème est lié à l'ego - certaines personnes préfèrent utiliser du code sous-optimal ou bogué plutôt que d'avoir quelqu'un d'autre plus raison qu'eux. Vous voulez probablement éviter de travailler avec ces personnes.
Le leadership, en particulier lorsque vous n'avez pas d'autorité positionnelle sur les gens, consiste à faire des suggestions raisonnables et à guider les autres vers un consensus. Si vous ne pouvez pas guider votre équipe vers une réunion des esprits, la question ne vaut peut-être pas la peine d'être pressée. Il y a probablement de plus gros poissons à faire frire.
la source
La voie à suivre est d'oublier la citation réelle et les diverses interprétations - c'est du dogmatisme de toute façon de se concentrer tellement sur une citation spécifique d'un gourou. Qui a dit que Knuth avait toujours raison de toute façon?
Au lieu de cela, concentrez-vous sur le projet en cours, le logiciel que vous développez avec les collègues avec lesquels vous n'êtes pas d'accord. Quelles sont les exigences pour des performances acceptables pour ce logiciel? Est-ce plus lent que ça? Optimisez ensuite.
Vous n'avez pas à l'appeler "optimisation", vous pouvez l'appeler "correction d'un bug", car il s'agit par définition d'un bug si l'implémentation ne se conforme pas aux exigences.
Plus généralement, il existe deux possibilités d'optimisation:
Le code optimisé est également plus court, plus simple à comprendre et plus facile à maintenir.
Le code optimisé est plus complexe à comprendre, prend plus de temps à écrire et à tester, ou serait plus complexe à changer à l'avenir si les exigences changent de manière inattendue.
Si le cas est (1), vous n'avez même pas à discuter de l'optimisation. Mais si (2) est le cas, alors vous vous engagez dans une décision de compromis . Il s'agit en fait d'une décision au niveau de l'entreprise, pas purement technique. Vous devez peser le coût de l'optimisation par rapport à l'avantage. Pour qu'il y ait même un avantage, l'inefficacité doit être un problème en premier lieu, que ce soit une mauvaise expérience utilisateur ou une augmentation significative du coût du matériel ou d'autres ressources.
la source
Je pense que la citation complète dans le contexte est instructive. Je vais copier à partir d'un post que j'ai fait sur Reddit sur le sujet:
- Donald Knuth, Programmation structurée avec go to Statements , ACM Computing Surveys, Vol 6, No. 4, déc. 1974, p.268
Le point, et l'implication, est qu'il y a des choses plus importantes à s'inquiéter que de porter votre attention sur l'optimisation trop tôt. Certes, vous devriez soigneusement considérer vos structures de données et algorithmes (c'est dans les 3%) mais vous ne devriez pas vous soucier de savoir si la soustraction est plus rapide que modulo (ceci étant dans les 97%) jusqu'à ce qu'il devienne clair qu'une optimisation de bas niveau est nécessaire.
Le premier n'est pas nécessairement l'optimisation au sens où le pensent vos collègues, mais c'est l'optimisation au sens où les algorithmes et les structures de données mal choisis sont sous - optimaux.
la source
D'après mon expérience, si vous obtenez régulièrement ce type d'opposition à l'optimisation , les gens ne se plaignent pas vraiment de l'optimisation. Ils se plaignent de ce que vous sacrifiez au nom de l'optimisation. Il s'agit généralement de lisibilité, de maintenabilité ou d'actualité. Si votre code est livré dans le même laps de temps et tout aussi facile à comprendre, les gens s'en moquent si vous utilisez des structures de données et des algorithmes plus efficaces. Ma suggestion dans ce cas est de travailler à rendre votre code plus élégant et plus facile à gérer.
Si vous obtenez ce genre d'opposition en ce qui concerne le code des autres, c'est généralement parce que vous proposez une quantité importante de retouches. Dans ces cas, vous avez vraiment besoin de mesures réelles pour montrer que cela en vaut la peine, ou essayez peut-être de vous impliquer plus tôt dans la phase de conception, avant que le code ne soit écrit. En d'autres termes, vous devez prouver que c'est dans les 3%. Si nous réécrivions tout le code qui n'était pas exactement ce que nous aimions, nous n'obtiendrions jamais rien accompli.
la source
Deque
de la bibliothèque standard Java afin de remplacer une énorme quantité de logique construite autour d'unArrayList
utilisé comme une pile tout en travaillant sur le code ... et cela a été marqué pour changement de révision. En d'autres termes, le réviseur voulait avoir plus de code qui est également plus lent et plus sujet aux bogues parce qu'il n'était pas familier avecDeque
.Il y a en effet beaucoup de malentendus à propos de cette citation, il est donc préférable de prendre du recul et de regarder quel est le problème réel. Le problème n'est pas tellement que vous ne devriez jamais "optimiser". C'est que "optimiser" n'est jamais une tâche que vous devriez entreprendre. Vous ne devez jamais vous réveiller le matin et vous dire "hé, je devrais optimiser le code aujourd'hui!".
Cela conduit à un effort inutile. Il suffit de regarder le code et de dire "je peux le rendre plus rapide!" conduit à beaucoup d'efforts pour faire quelque chose de plus rapide qui était assez rapide en premier lieu. Vous pourriez être fier de vous dire que vous avez fait un peu de code quatre fois plus rapidement, mais si ce code était un calcul qui s'est produit lors d'une pression sur un bouton, et qu'il a fallu 10 ms en premier lieu avant d'afficher à un utilisateur humain, personne va s'en foutre.
C'est le "prématuré" dans "l'optimisation prématurée". Quand n'est-ce pas "prématuré"? Lorsque les clients vous disent "c'est trop lent, corrigez-le!" C'est alors que vous creusez le code et essayez de le rendre plus rapide.
Cela ne signifie pas que vous devez éteindre votre cerveau. Cela ne signifie pas que vous devez conserver 10 000 enregistrements clients dans une liste liée individuellement. Vous devez toujours comprendre les impacts sur les performances de ce que vous faites et agir en conséquence. Mais l'idée est que vous ne passez pas de temps supplémentaire à essayer délibérément de l'accélérer. Vous choisissez simplement le choix le plus performant parmi des choix par ailleurs égaux.
la source
Vous pouvez soit faire les choses de la mauvaise façon, soit faire les bonnes choses.
Souvent, les choses sont mal faites et le code est refactorisé pour qu'il soit fait de la bonne façon. Si vous allez écrire du nouveau code et que vous savez que vous pouvez faire les choses de la bonne manière sans pénalité majeure, je me tromperais du côté de le faire de la bonne manière. (Notez qu'après les tests de performances, etc., certaines choses peuvent devoir changer - mais ce n'est pas grave. Alternativement, une implémentation complètement naïve est rarement, voire jamais, correcte.)
Ce n'est pas nécessairement une optimisation prématurée si vous a) savez que cela vous aidera à l'avenir ou b) sachez que le chemin sous-optimal entraînera des problèmes sur la route. C'est comme un jeu d'échecs, vraiment.
Je pense que les gens auront tendance à vouloir bien faire les choses plutôt que de les faire mal. Utilisez-le lorsque vous discutez de stratégies alternatives avec vos pairs.
la source
Cela semble être un problème de communication et non un problème de programmation. Essayez de comprendre pourquoi les gens ressentent ce qu'ils ressentent et essayez de cristalliser pourquoi vous pensez que votre voie serait meilleure. Lorsque vous avez fait cela, ne lancez pas d'argument de confrontation où votre objectif est de dire aux autres pourquoi ils ont tort et que vous avez raison. Expliquez vos pensées et vos sentiments et laissez les gens réagir à cela. Si vous ne parvenez à aucun consensus et que vous pensez que c'est un problème vraiment critique, alors vous avez probablement de sérieux problèmes dans l'équipe dans son ensemble.
Plus axé sur la programmation réelle, ne perdez pas de temps sur de longs arguments sur quelque chose que vous avez juste le sentiment instinctif est "plus rapide". Si vous voyez quelqu'un écrire une méthode qui est appelée une fois par requête dans une application web et qu'elle a une complexité temporelle O (n ^ 2) lorsque vous SAVEZ que c'est vraiment un problème de temps O (log (n)), alors bien sûr, si c'est le cas une évidence, allez-y.
Cependant, en tant qu'humains, nous, les programmeurs, sommes vraiment mauvais (et je veux dire AWFUL) pour deviner quelles parties de nos applications qui goulot d'étranglement. Eric Lippert écrit sur ce sujet intéressant dans cet article de blog. Privilégiez toujours la maintenabilité. Tous les problèmes de performances qui peuvent éventuellement être trouvés peuvent ensuite être résolus (enfin, relativement) lorsque vous avez plus d'informations.
la source