web-dev-qa-db-fra.com

Comment faire face aux idées fausses sur "L'optimisation prématurée est la racine de tout mal"?

J'ai rencontré de nombreuses personnes qui sont dogmatiquement contre tout ce qui peut être considérée comme une "optimisation" dans le sens général de la Parole, et ils citent très souvent Verbatim la citation (partielle) "L'optimisation prématurée est la racine de tout le mal" En raison de la justification de leur position, impliquant qu'ils interprètent tout ce que je parle d'être "optimisation prématurée". Cependant, ces vues sont parfois si ridiculement enracinées de rejettent à peu près tout type d'écart algorithmique ou de structure de données à partir de la mise en œuvre "naïve" la plus pure ... ou du moins des écarts de la manière dont ils ont fait des choses avant. Comment peut-on approcher des personnes comme celle-ci d'une manière de les faire "ouvrir leurs oreilles" après avoir fermé de l'audience sur "Performance" ou "Optimisation"? Comment puis-je discuter d'un sujet de conception/mise en œuvre qui a un impact sur la performance sans que les gens pensent instantanément: "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 mal" ou non déjà été couverte ici ainsi que dans d'autres coins du Web , et il a déjà J'ai été discuté Comment reconnaître quand l'optimisation est prématurée et donc mal , mais malheureusement, il reste des gens dans le monde réel qui ne sont pas tout aussi ouverts aux défis de leur foi en anti-optimisation.

Tentatives précédentes

Quelques fois, j'ai essayé de fournir la citation complète de Donald Knuth afin d'expliquer que "l'optimisation prématurée est mauvaise" ↛ "Tout optimisation est mauvais":

Nous devrions oublier de petites gains d'efficacité, dire environ 97% du temps: l'optimisation prématurée est la racine de tout mal. Pourtant, nous ne devrions pas transmettre nos opportunités dans ce critique 3%.

Cependant, lors de la fourniture de la citation entière, ces personnes deviennent parfois plus convaincues que ce que je fais est une optimisation prématurée ™ et de creuser et de refuser d'écouter. C'est presque comme si le mot "optimisation" les effraie: à quelques reprises, j'ai pu proposer des changements de code réels améliorant la performance sans qu'ils soient opposés en évitant simplement l'utilisation du mot "optimiz (e | ation)" ( et "performance" également - ce mot est effrayant aussi) et utilise plutôt une expression comme une "architecture alternative" ou "mise en œuvre améliorée". Pour cette raison, cela semble vraiment que cela soit vraiment le dogmatisme et non en fait d'évaluer ce que je dis de manière critique puis de le rejeter comme non nécessaire et/ou trop coûteux.

26
errantlinguist

Il semble que vous recherchiez d'abord des raccourcis pour ne pas essayer la "mise en œuvre naïve la plus pure" et mettre en œuvre directement une "solution plus sophistiquée parce que 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 difficiles ou techniques Arguments pour prouver que la mise en œuvre naïve est ou sera trop lente, vous êtes très probablement faux, et ce que vous faites - est Optimisation prématurée. Et essayer de discuter avec Knuth est le contraire d'avoir un fait difficile.

Dans mon expérience, vous devrez devoir mordre la balle et essayer d'abord la "mise en œuvre naïf" (et sera probablement étonnée à quelle fréquence cela est assez rapide), ou vous ferez au moins une estimation approximative sur le temps de fonctionnement, comme:

"La mise en œuvre naïf sera O (N³) et n est plus grand que 100 000; cela va courir quelques jours, tandis que la mise en œuvre non so-naïve s'exécutera dans O (n), ce qui ne prendra que quelques-unes minutes ".

Seulement avec de tels arguments à la main, vous pouvez être sûr que votre optimisation n'est pas prématurée.

Il y a iMho seulement ne exception près à partir de ceci: lorsque la solution plus rapide est également la plus simple et la plus propre, vous devez utiliser la solution plus rapide dès le début. L'exemple standard est celui de l'utilisation d'un dictionnaire au lieu d'une liste permettant d'éviter un code de boucle inutile pour les recherches ou de 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 résultat. filtré par la suite dans le code. Si vous avez un tel cas, ne discutez pas des performances - La performance peut être un avantage supplémentaire, mais probablement non pertinent, et lorsque vous en parlez, les gens pourraient être tentés d'utiliser Knuth contre vous. Argumenter sur la lisibilité, le code plus court, le code de nettoyage, la maintenabilité - pas besoin de "masquer" quoi que ce soit ici, mais parce que ceux (et seulement ceux) sont les arguments corrects ici.

Pour mon expérience, ce dernier cas est rare - plus le cas échéant est que l'on peut d'abord mettre en place une solution simple et naïve qui est mieux compréhensible et moins telle que celle d'une erreur plus compliquée, mais probablement plus rapide.

Et bien sûr, vous devez connaître les exigences et le cas d'utilisation assez bien pour savoir quelles performances sont acceptables et que les choses deviennent "trop lentes" dans les yeux de vos utilisateurs. Dans un monde idéal, vous obtiendrez une performance officielle de votre client, mais dans des projets du monde réel, la performance requise est souvent une zone grise, ce que vos utilisateurs ne vous indiqueront que lorsqu'ils notent que le programme se comporte "trop lent" dans la production. Et souvent, c'est le seul moyen de découverte que quelque chose est trop lent - les commentaires de l'utilisateur, et vous n'avez ensuite pas besoin de citer Knuth pour convaincre vos coéquipiers que leur "mise en œuvre naïve" n'était pas suffisante.

35
Doc Brown

Demandez-vous ceci:

  • Le logiciel ne répond pas aux spécifications de performance?
  • Le logiciel a-t-il un problème de performance?

Ce sont des raisons d'optimiser. Donc, si les gens sont opposés, il suffit de leur montrer la spécification et de les revenir et d'expliquer que nous devons optimiser parce que nous ne rencontrons pas les spécifications. Autre que cela, on aurait du mal à convaincre d'autres que l'optimisation est nécessaire.

Je pense que le point principal de la citation est que si vous n'avez pas de problème, n'effectuez pas d'optimisation inutile au fil du temps et de l'énergie pouvant être dépensée ailleurs. D'une prospective professionnelle, cela est parfaitement logique.

Secondaire, pour ceux qui craignent l'optimisation, toujours sauvegarder les résultats de performance avec des métriques. Combien plus vite est le code? Combien la performance s'est-elle améliorée par la précédente? Si l'on a passé deux semaines seulement pour améliorer le code de 2% sur la version précédente, si j'étais votre patron, je ne serais pas heureux. Ces deux semaines auraient pu être consacrées à la mise en œuvre d'une nouvelle fonctionnalité qui pourrait attirer plus de clients et gagner plus d'argent.

Enfin, la plupart des logiciels ne doivent pas être très optimisés. Seulement dans quelques industries spécialisées est une vitesse vraiment importante. Donc, la plupart du temps, on peut utiliser des bibliothèques et des cadres préexistants à un bon effet.

18
Jon Raynor

Comment travailler avec des personnes qui shasewall une discussion à la minute où cela a à voir avec la performance?

Commencez par des principes partagés qui s'appuient sur la direction stratégique de votre groupe.

Mes principes:

Mes principes personnels sur le code de la rédaction sont d'abord à viser l'exactitude de mon programme, puis de le profiler et de déterminer s'il a besoin d'optimisation. 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 si c'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 de code plus rapide.

Cependant, il est connu, manifestement de meilleurs choix dans le code que l'on puisse faire. Je préférerais bien comprendre mon premier projet pour plusieurs raisons:

  1. Si je comprends bien la première fois, je peux oublier la mise en œuvre (profiter de la cachette de l'information), et je n'enclut pas mon code avec TODOS.
  2. D'autres (en particulier ceux qui apprennent uniquement sur le tas), voient cela fait la bonne façon, et ils apprennent et utilisent le même style de code à l'avenir. Inversement, s'ils me voient le faire dans le mauvais sens, ils le feront aussi du mauvais chemin aussi.

En supposant que le besoin d'optimisation est correct

En supposant qu'il s'agisse d'une partie vraiment importante de votre code qui a besoin d'optimisation, vous pouvez dire à la parabole de Schlemiel le peintre ou insister sur le reste de la citation:

"Les programmeurs gaspillent énormes de temps en pensant, ou se soucient de la rapidité des parties non critiques de leurs programmes, et ces tentatives d'efficacité ont effectivement un impact négatif fort lors du débogage et de la maintenance sont pris en compte. Nous devrions oublier de petites gains d'efficacité, disons à propos de 97% du temps: l'optimisation prématurée est la racine de tout mal. Pourtant, nous ne devrions pas transmettre nos opportunités dans ce critique 3%. " - Donald Knuth

Peser les coûts de 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 risquez de conserver la mise en œuvre secondaire dans une fonction ou une sous-classe différente et d'appliquer les mêmes instances de manière à ce qu'il ne soit pas question qu'il est correct. Plus tard, si vous proférez de votre code et que vous trouvez la mise en œuvre naïve comme un goulot d'étranglement, vous pouvez basculer votre code optimisé et améliorer de manière manifeste votre programme.

Direction

Parfois, le problème est l'ego - Certaines personnes préfèrent utiliser le code suboptimal ou buggy que d'avoir quelqu'un d'autre plus juste que ce qu'ils sont. Vous voulez probablement éviter de travailler avec ces personnes.

Leadership, surtout lorsque vous n'avez pas d'autorité positionnelle sur les gens, consiste à faire des suggestions raisonnables et à guider les autres à un consensus. Si vous ne pouvez pas guider votre équipe à une réunion de l'esprit, la question ne vaut peut-être pas la peine d'appuyer. Il y a probablement de plus gros poissons à frire.

7
Aaron Hall

La voie à suivre est d'oublier la citation actuelle et les différentes interprétations - il est dogmatismatinique de toute façon de se concentrer sur une citation spécifique par un gourou. Qui a dit que Knuth a toujours raison de toute façon?

Au lieu de cela, concentrez-vous sur le projet à la main, le logiciel que vous développez avec les collègues que vous êtes en désaccord avec. Quelle est la Configuration requise pour des performances acceptables pour ce logiciel? Est-ce plus lent que cela? Puis optimiser.

Vous n'êtes pas obligé de l'appeler "Optimisation", vous pouvez l'appeler "Fixer un bogue", car il s'agit d'un bogue si la mise en œuvre ne parvient pas à être conforme aux exigences.

Plus généralement, il existe deux possibilités concernant les optimisations:

  1. Le code optimisé est également plus court, plus simple à comprendre et plus facile à entretenir.

  2. Le code optimisé est plus complexe à comprendre, prend plus de temps pour écrire et tester, ou serait plus complexe à modifier à 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, vous vous engagez dans un Trade-off décision. C'est en fait une décision de niveau commercial, pas purement une décision technique. Vous devez peser le coût de l'optimisation de l'avantage. Pour y avoir même un avantage, l'inefficacité doit être un problème en premier lieu, soit comme une mauvaise expérience utilisateur, soit une augmentation significative des coûts de matériel ou d'autres ressources.

6
JacquesB

Je pense que la citation complète dans le contexte est instructif. Je copierai d'un message que j'ai fait sur Reddit sur le sujet:

Il ne fait aucun doute que le grail d'efficacité conduit à des abus. Les programmeurs gaspillent des quantités énormes de temps en pensant, ou se préoccupant de la rapidité des parties non critiques de leurs programmes, et ces tentatives d'efficacité ont effectivement un impact négatif fort lors du débogage et de la maintenance. Nous devrions oublier de petites gains d'efficacité, dire environ 97% du temps: L'optimisation prématurée est la racine de tout mal.

Pourtant, nous ne devrions pas transmettre nos opportunités dans ce critique 3%. Un bon programmeur ne sera pas bercé dans la complaisance par ce raisonnement, il sera sage de Regardez attentivement le code critique; Mais seulement après l'identification de ce code.

- Donald Knuth, Programmation structurée avec Aller à des instructions, ACM Surveys informatique, vol 6, n ° 4, déc. 1974, p.268

Le point et l'implication, c'est qu'il existe des choses plus importantes à craindre que de mettre votre attention à l'optimisation trop tôt. Certainement, vous devez considérer avec précaution vos structures de données et vos algorithmes (c'est dans les 3%), mais vous ne devriez pas vous inquiéter de savoir si la soustraction est plus rapide que MODULO (ceci étant dans 97%) jusqu'à ce qu'il soit clair. une optimisation de nombril est nécessaire.

Le premier n'est pas nécessairement d'optimisation en ce sens que vos collègues pensent, mais c'est l'optimisation en ce sens que des algorithmes et des structures de données mal choisies sont suboptimal.

4
greyfade

Dans mon expérience, si vous obtenez ce type d'opposition à l'optimisation régulièrement, les gens ne se plaignent pas vraiment de l'optimisation. Ils se plaignent de ce que vous sacrifiez au nom de l'optimisation. C'est généralement la lisibilité, la maintenabilité ou la rapidité. Si votre code est livré dans le même temps, et simplement aussi facile à comprendre, les gens ne pouvaient pas se moquer de moins 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 maintenu.

Si vous obtenez ce type d'opposition en ce qui concerne le code des autres personnes, c'est généralement parce que vous suggérez une quantité importante de retravaque. Dans ces cas, vous avez vraiment besoin de mesures réelles pour montrer que cela vaut la peine d'effort, ou peut-être essayer 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 comment nous l'avons aimé, nous n'aurions jamais rien accompli.

3
Karl Bielefeldt

Il y a en effet beaucoup de malentendus sur cette citation, il est donc préférable de reculer et de regarder quelle est la question réelle. 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 déterminer. Vous ne devriez jamais vous réveiller le matin et vous dire "Hey, je devrais optimiser le code aujourd'hui!".

Cela conduit à des efforts gaspillés. Juste regarder le code et dire "Je peux le rendre plus rapide!" conduit à beaucoup d'efforts rendre quelque chose plus rapide qui était assez rapide en premier lieu. Vous trouverez peut-être la fierté de vous dire que vous avez fait un peu de code quatre fois plus rapide, mais si ce code était un calcul sur une touche, appuyez sur 10 ms en première place avant d'afficher un utilisateur humain, personne ne va se soucier.

C'est la "prématurée" dans "Optimisation prématurée". Quand est-ce pas "prématuré"? Lorsque les clients vous disent "c'est trop lent, fixez-le!" C'est lorsque vous creusez dans le code et essayez de le rendre plus rapide.

Cela ne signifie pas que vous devriez éteindre votre cerveau. Cela ne signifie pas que vous devriez conserver 10 000 enregistrements de clients dans une liste individuellement liée. Vous devez toujours comprendre les impacts de performance de ce que vous faites à l'esprit et agissez en conséquence. Mais l'idée est que vous ne dépensez pas de temps supplémentaire d'essayer de le rendre plus rapide. Vous choisissez simplement le choix plus performant des choix par ailleurs égaux.

2
Gort the Robot

Cela semble être un problème de communication et non un problème de programmation. Essayez de comprendre pourquoi les gens ressentent la façon dont ils le font et essaient de cristalliser pourquoi vous pensez que votre chemin serait mieux. Lorsque vous avez fait cela, ne commencez pas un argument conflictural 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 simplement les gens réagir à cela. Si vous ne pouvez pas atteindre une sorte de consensus et que vous vous sentez comme si ceci est une question vraiment critique, vous avez probablement des problèmes graves dans l'ensemble de l'équipe.

Plus axé sur la programmation réelle, ne perdez pas de temps sur de longues arguments sur quelque chose que vous avez simplement un sentiment d'intestin est "plus rapide". Si vous voyez une personne qui écrit une méthode appelée une fois par demande dans une application Web et qu'elle a une complexité de temps O (n ^ 2) lorsque vous savez que c'est vraiment un O(log(n)) PROBLÈME TIME, alors sûr, si c'est un certitude aussi bien, allez-y.

Sachez cependant, comme les humains, nous les programmeurs sont vraiment mauvais (et je veux dire affreux) à deviner quelles parties de nos applications qui vont goulot d'étranglement. Eric Lippert écrit à propos de ce sujet intéressant dans Ceci Blog Post. Toujours favoriser la maintenabilité. Toutes les problèmes de performance qui sont finalement trouvés peuvent alors facilement être réparés (bien, relativement) lorsque vous avez plus d'informations.

1
sara

Vous pouvez soit faire des choses dans le mauvais sens, soit faire la bonne façon.

Souvent, des choses sont faites dans le mauvais sens et le code est refactored afin que cela soit fait de bonne manière. Si vous allez écrire un nouveau code et que vous savez que vous pouvez faire des choses la bonne façon sans une pénalité majeure, je ferais simplement envie de le faire de la bonne façon. (Notez que, après les tests de performance, etc. Certaines choses peuvent avoir besoin de changer - mais ça va. Alternativement, une implémentation totalement naïve est rarement, voire jamais, à droite.)

Ce n'est pas nécessairement une optimisation prématurée si vous) savez que cela aidera à l'avenir ou à B) SAVOIR que le chemin sous-optimal conduira à des problèmes sur la route. C'est comme un jeu d'échecs, vraiment.

Je pense que les gens auront tendance à vouloir faire les choses correctement, plutôt que de les faire mal. Utilisez-le lorsque vous discutez des stratégies alternatives avec vos pairs.

1
lunchmeat317