L'optimisation prématurée est-elle vraiment la racine de tout mal?

215

Un de mes collègues a engagé aujourd'hui une classe appelée ThreadLocalFormat, qui a essentiellement déplacé des instances de classes au format Java dans un thread local, car elles ne sont pas thread-safe et sont "relativement coûteuses" à créer. J'ai écrit un test rapide et calculé que je pouvais créer 200 000 instances par seconde. Je lui ai demandé s'il en créait autant, ce à quoi il a répondu "loin de tout cela". C'est un excellent programmeur et tous les membres de l'équipe sont extrêmement compétents. Nous n'avons donc aucun problème à comprendre le code résultant, mais il s'agissait clairement d'optimiser là où il n'y a pas de réel besoin. Il a annulé le code à ma demande. Qu'est-ce que tu penses? S'agit-il d'une "optimisation prématurée" et quelle est sa gravité?

Craig Day
la source
23
Je pense que vous devez faire la distinction entre optimisation prématurée et optimisation inutile. Prématuré me suggère «trop tôt dans le cycle de vie» alors que non nécessaire suggère «n'ajoute pas de valeur significative». OMI, l'exigence d'optimisation tardive implique une conception de mauvaise qualité.
110
Oui, mais le mal est un polynôme et a de nombreuses racines, certaines sont complexes.
dan_waterworth
7
Vous devriez considérer que Knuth a écrit ceci en 1974. Dans les années soixante-dix, il n'était pas aussi facile d'écrire des programmes lents qu'aujourd'hui. Il a écrit avec Pascal à l'esprit et non avec Java ou PHP.
Ceving
4
Non. La cupidité est la racine de tout mal.
Tulains Córdova
12
@ceving Dans les années 70, il était aussi facile qu'aujourd'hui d'écrire des programmes lents. Si vous choisissez le mauvais algorithme ou la mauvaise structure de données, alors BAM! Mauvaise performance partout. On pourrait dire le contraire. Aujourd'hui, ce sont beaucoup plus d'outils et il devrait être inexcusable qu'un programmeur continue d'écrire un logiciel qui souffre de la sauvegarde la plus élémentaire. Le parallélisme est devenu presque une marchandise et nous souffrons encore. La lenteur des performances ne peut être imputée au langage, aux outils, au processeur ou à la mémoire. C'est un équilibre délicat entre tant de choses, c'est pourquoi il est presque impossible d'optimiser tôt.
Alex

Réponses:

322

Il est important de garder à l'esprit la citation complète:

Nous devrions oublier les petites efficacités, disons environ 97% du temps: l'optimisation prématurée est la racine de tout mal. Pourtant, nous ne devrions pas laisser passer nos opportunités dans ces 3% critiques.

Cela signifie qu'en l'absence de problèmes de performance mesurés, vous ne devez pas optimiser, car vous pensez obtenir un gain de performance. Il y a des optimisations évidentes (comme ne pas faire de concaténation de chaînes dans une boucle étroite), mais tout ce qui n'est pas une optimisation triviale doit être évité jusqu'à ce qu'il puisse être mesuré.

Le plus gros problème avec "l'optimisation prématurée" est qu'il peut introduire des bogues inattendus et peut être une perte de temps énorme.

Scott Dorman
la source
7
Étant de Donald Knuth, je ne serais pas surpris s'il avait des preuves à l'appui. BTW, Src: Programmation structurée avec les déclarations, ACM Journal Computing Surveys, Vol 6, N ° 4, décembre 1974. p.268. citeseerx.ist.psu.edu/viewdoc/…
mctylr
28
... Un bon programmeur ne sera pas séduit par un tel raisonnement, il sera sage de regarder attentivement le code critique; mais seulement après que ce code a été identifié (reste de la citation plus complète)
mctylr
21
Aujourd'hui, un représentant de 20 000 utilisateurs m'a dit que l' optimisation était prématurée HashSetplutôt que Listoptimisée. Le cas d'utilisation en question était une collection initialisée de manière statique dont le seul but était de servir de table de recherche. Je ne pense pas que je me trompe en disant qu'il y a une différence dans la sélection du bon outil pour l'optimisation du travail par rapport à l'optimisation prématurée. Je pense que votre message confirme cette philosophie: There are obvious optimizations...anything that isn't trivially clear optimization should be avoided until it can be measured.l’optimisation d’un HashSet a été minutieusement mesurée et documentée.
écraser
9
@crush: yes: Setest aussi plus sémantiquement correct et informatif que ne l'est Listdonc l'optimisation.
Erik Allik
7
Je voudrais ajouter que l'optimisation prématurée ne doit pas être confondue avec la conception de l'ensemble de votre architecture d'application pour qu'elle soit rapide, évolutive et facilement optimisable.
Erik Allik
111

Les micro- optimisations prématurées sont la racine de tout mal, car les micro-optimisations omettent le contexte. Ils ne se comportent presque jamais comme ils sont attendus.

Quelles sont les bonnes optimisations précoces dans l'ordre d'importance:

  • Optimisations architecturales (structure de l'application, la manière dont elle est composée et stratifiée)
  • Optimisations des flux de données (à l'intérieur et à l'extérieur de l'application)

Quelques optimisations en milieu de développement:

  • Structures de données, introduisez de nouvelles structures de données plus performantes ou moins lourdes, si nécessaire
  • Algorithmes (c'est maintenant le bon moment pour décider entre quicksort3 et heapsort ;-))

Quelques optimisations de fin de cycle de développement

  • Recherche de points chauds de code (boucles serrées, qui devraient être optimisées)
  • Optimisations basées sur le profilage des parties informatiques du code
  • Les micro-optimisations peuvent maintenant être effectuées comme elles le sont dans le contexte de l'application et leur impact peut être mesuré correctement.

Toutes les optimisations initiales ne sont pas mauvaises, mais les micro-optimisations sont mauvaises si elles sont effectuées au mauvais moment du cycle de vie du développement , car elles peuvent affecter négativement l'architecture, peuvent affecter négativement la productivité initiale, peuvent nuire aux performances ou même avoir un effet néfaste à la fin. développement en raison de conditions environnementales différentes.

Si la performance est une préoccupation (et devrait toujours l'être), pensez toujours grand . La performance est une image plus grande et ne concerne pas des choses comme: devrais-je utiliser int ou long ? Choisissez Top Down lorsque vous travaillez avec des performances plutôt que de bas en haut .

Pop Catalin
la source
"Optimisation: Votre pire ennemi", de Joseph M. Nouvel arrivant: flounder.com/optimization.htm
Ron Rouble
53

l'optimisation sans mesure préalable est presque toujours prématurée.

Je crois que c'est vrai dans ce cas, et vrai aussi dans le cas général.

Jeff Atwood
la source
Ici ici! L'optimisation non prise en compte rend le code non maintenable et est souvent la cause de problèmes de performances. Par exemple, vous programmez plusieurs programmes en même temps parce que vous imaginez que cela pourrait améliorer les performances, mais la vraie solution aurait été de créer plusieurs processus trop complexes à implémenter.
James Anderson
sauf si c'est documenté.
Nawfal
Oui. entièrement d'accord. Il faut d'abord mesurer. Il est impossible de savoir où se trouvent les goulets d'étranglement avant de tester quelque chose de bout en bout et de mesurer chacune des étapes.
Oliver Watkins
Les mesures peuvent mentir. J'ai vu des spécialistes chevronnés passer des semaines à lire des traces et à dresser des profils pour se cogner contre un mur où ils pensaient qu'il n'y avait plus rien à gagner. Ensuite, j'ai lu l'intégralité du code et en quelques heures, j'ai apporté quelques modifications globales pour obtenir une amélioration de 10 fois. Les profils ne présentaient aucun chemin chaud, car tout le code était mal conçu. J'ai également vu des profileurs réclamer des hotpaths où il ne devrait pas y en avoir. Une personne "mesurant" aurait optimisé le hotpath, mais elle aurait dû se rendre compte que celui-ci était le symptôme d'un autre code médiocre.
Bengie
42

L'optimisation est "pervers" si

  • code moins clair
  • beaucoup plus de code
  • code moins sécurisé
  • temps perdu par les programmeurs

Dans votre cas, il semble qu’un peu de temps de programmation ait déjà été dépensé, le code n’était pas trop complexe (votre devin devrait pouvoir être compris par tout le monde de l’équipe), et le code est un peu plus fiable thread safe maintenant, si j'ai bien compris votre description). Cela ressemble à un peu mal. :)

John Mulder
la source
4
Seulement si le coût, selon vos points, est supérieur à la valeur amortie livrée. La complexité introduit souvent de la valeur et, dans ces cas, elle peut être encapsulée de manière à satisfaire vos critères. Il est également réutilisé et continue de fournir plus de valeur.
1
Ces deux premiers points sont les plus importants pour moi, le quatrième étant une conséquence négative d’une optimisation prématurée. En particulier, c'est un drapeau rouge chaque fois que je vois quelqu'un réimplémenter des fonctionnalités à partir d'une bibliothèque standard. Par exemple, j'ai déjà vu quelqu'un implémenter des routines personnalisées pour la manipulation de chaînes car il craignait que les commandes intégrées ne soient trop lentes.
route
8
Rendre le code thread sûr n'est pas une optimisation.
mattnz
38

Je suis surpris que cette question ait 5 ans et pourtant, personne n'a écrit plus de ce que Knuth avait à dire que quelques phrases. Les quelques paragraphes entourant la célèbre citation l'expliquent assez bien. Le document cité s'appelle " Programmated Structured with go to Statements ". Bien qu'il existe depuis près de 40 ans, il traite d'un sujet controversé et d'un mouvement pour le logiciel qui n'existe plus, et contient des exemples dans des langages de programmation que beaucoup de gens n'ont jamais connus. entendu parler, une quantité étonnamment grande de ce qu'il dit est toujours valable.

Voici une citation plus grande (à partir de la page 8 du pdf, page 268 de l'original):

L’amélioration de la vitesse de l’exemple 2 à l’exemple 2a n’est que d’environ 12%, ce que beaucoup de gens jugeraient insignifiant. La sagesse conventionnelle partagée par de nombreux ingénieurs en logiciel actuels appelle à ignorer l'efficacité dans les petites entreprises; mais je crois que ceci est simplement une réaction excessive aux abus qu’ils voient être pratiqué par des programmeurs stupides qui ne peuvent ni déboguer ni maintenir leurs programmes "optimisés". Dans les disciplines d'ingénierie établies, une amélioration de 12%, facilement obtenue, n'est jamais considérée comme marginale; et je crois que le même point de vue devrait prévaloir en génie logiciel. Bien sûr, je ne me soucierais pas de faire de telles optimisations pour un travail ponctuel, mais lorsqu'il s'agit de préparer des programmes de qualité, je ne veux pas me limiter à des outils qui me nient de manière aussi efficace.

Il ne fait aucun doute que le graal de l'efficacité conduit à des abus. Les programmeurs perdent énormément de temps à réfléchir à la vitesse des parties non critiques de leurs programmes, ou à s’inquiéter de ceux-ci, et ces tentatives d’efficacité ont en réalité un impact très négatif sur le débogage et la maintenance. Nous devrions oublier les petites efficacités, disons environ 97% du temps: l'optimisation prématurée est la racine de tout mal.

Pourtant, nous ne devrions pas laisser passer nos opportunités dans ces 3% critiques. Un bon programmeur ne se laissera pas aller à la complaisance par un tel raisonnement, il sera sage de regarder attentivement le code critique; mais seulement après que ce code a été identifié. C’est souvent une erreur de juger a priori des parties d’un programme qui sont vraiment essentielles, car l’expérience universelle des programmeurs qui utilisent des outils de mesure a été l’échec de leurs suppositions intuitives.

Un autre bon point de la page précédente:

Mon propre style de programmation a bien sûr changé au cours de la dernière décennie, en fonction des tendances de l'époque (par exemple, je ne suis plus aussi compliqué et j'utilise moins de go to to), mais le changement majeur dans mon style est dû à ce phénomène de boucle intérieure. Je regarde maintenant d'un œil extrêmement jaunâtre toutes les opérations d'une boucle interne critique, cherchant à modifier mon programme et la structure de données (comme dans le passage de l'exemple 1 à l'exemple 2) afin d'éliminer certaines opérations. Les raisons de cette approche sont les suivantes: a) cela ne prend pas longtemps, car la boucle interne est courte; b) le gain est réel; et c) je peux alors me permettre d’être moins efficace dans les autres parties de mes programmes, qui sont donc plus lisibles et plus faciles à écrire et à déboguer.

Michael Shaw
la source
20

J'ai souvent vu cette citation utilisée pour justifier un code ou un code manifestement mauvais qui, même si ses performances n'ont pas été mesurées, pourrait probablement être rendu plus rapide, sans augmenter la taille du code ni en compromettre la lisibilité.

En général, je pense que les premières micro-optimisations peuvent être une mauvaise idée. Cependant, les macro-optimisations (telles que le choix d’un algorithme O (log N) au lieu de O (N ^ 2)) sont souvent utiles et devraient être effectuées tôt, car il peut être inutile d’écrire un algorithme O (N ^ 2) et puis le jeter complètement en faveur d'une approche O (log N).

Notez que les mots peuvent être : si l’algorithme O (N ^ 2) est simple et facile à écrire, vous pouvez le jeter plus tard sans trop de culpabilité s’il s’avère trop lent. Toutefois, si les deux algorithmes sont aussi complexes ou si la charge de travail attendue est si importante que vous savez déjà que vous aurez besoin du plus rapide, l'optimisation anticipée est une bonne décision d'ingénierie qui réduira à terme votre charge de travail totale.

Ainsi, en général, je pense que la bonne approche consiste à déterminer quelles sont vos options avant de commencer à écrire du code et à choisir consciemment le meilleur algorithme pour votre situation. Plus important encore, l'expression "l'optimisation prématurée est la racine de tout le mal" n'est pas une excuse pour l'ignorance. Les promoteurs de carrière devraient avoir une idée générale du coût des opérations courantes; ils devraient savoir, par exemple,

  • que les chaînes coûtent plus cher que les chiffres
  • les langages dynamiques sont beaucoup plus lents que les langages statiques
  • les avantages des listes matricielles / vectorielles par rapport aux listes chaînées, et inversement
  • quand utiliser une hashtable, quand utiliser une carte triée et quand utiliser un tas
  • que (s'ils fonctionnent avec des appareils mobiles) "double" et "int" ont des performances similaires sur les ordinateurs de bureau (la PF peut même être plus rapide) mais "double" peut être cent fois plus lent sur des appareils mobiles bas de gamme sans FPU;
  • que le transfert de données sur Internet est plus lent que l’accès au disque dur, que les disques durs sont beaucoup plus lents que la RAM, beaucoup plus lents que le cache et les registres L1 et que les opérations Internet peuvent se bloquer indéfiniment (et échouer à tout moment).

Et les développeurs doivent être familiarisés avec une boîte à outils de structures de données et d'algorithmes afin de pouvoir facilement utiliser les bons outils pour le travail.

Avoir beaucoup de connaissances et une boîte à outils personnelle vous permet d’optimiser presque sans effort. Il est diabolique de consacrer beaucoup d’efforts à une optimisation qui pourrait ne pas être inutile (et j’admets avoir été pris au piège plus d’une fois). Mais lorsque l'optimisation est aussi simple que de choisir un ensemble / hashtable au lieu d'un tableau ou de stocker une liste de nombres dans double [] au lieu de string [], pourquoi pas? Je ne suis peut-être pas d'accord avec Knuth mais je pense qu'il parlait de l'optimisation de bas niveau alors que je parle de l'optimisation de haut niveau.

N'oubliez pas que cette citation date de 1974. En 1974, les ordinateurs étaient lents et la puissance de calcul coûteuse, ce qui donnait à certains développeurs une tendance à l'optimisation excessive, ligne par ligne. Je pense que c'est ce que Knuth a poussé. Il ne disait pas "ne t'inquiète pas du tout pour la performance", car en 1974, ce ne serait que des paroles folles. Knuth expliquait comment optimiser; En bref, il convient de se concentrer uniquement sur les goulots d'étranglement et avant de le faire, vous devez effectuer des mesures pour trouver les goulots d'étranglement.

Notez que vous ne pouvez pas trouver les goulots d'étranglement avant d'avoir écrit un programme à mesurer, ce qui signifie que certaines décisions de performance doivent être prises avant que quoi que ce soit n'existe à mesurer. Parfois, ces décisions sont difficiles à changer si vous vous trompez. Pour cette raison, il est bon d’avoir une idée générale du coût de la chose afin de pouvoir prendre des décisions raisonnables en l’absence de données fiables.

L'optimisation et le degré d'inquiétude lié aux performances dépendent du travail à effectuer. Lorsque vous écrivez des scripts que vous n'exécuterez que quelques fois, vous soucier de la performance est généralement une perte de temps totale. Mais si vous travaillez pour Microsoft ou Oracle et que vous travaillez sur une bibliothèque que des milliers d'autres développeurs vont utiliser de mille façons différentes, il peut être rentable de l'optimiser, de façon à pouvoir couvrir tous les aspects divers. utiliser les cas efficacement. Même dans ce cas, le besoin de performance doit toujours être mis en balance avec le besoin de lisibilité, de maintenabilité, d’élégance, d’extensibilité, etc.

Qwertie
la source
2
Amen. L'optimisation prématurée est beaucoup trop libérale de nos jours par des personnes qui essaient de justifier l'utilisation d'un mauvais outil pour le poste. Si vous connaissez le bon outil pour le travail à l'avance, il n'y a aucune excuse pour ne pas l'utiliser.
écraser
13

Personnellement, comme indiqué dans un précédent fil , je ne pense pas que l'optimisation précoce soit mauvaise dans les situations où vous savez que vous rencontrerez des problèmes de performances. Par exemple, j'écris des logiciels de modélisation et d'analyse de surface, où je traite régulièrement avec des dizaines de millions d'entités. Planifier pour une performance optimale au stade de la conception est de loin supérieur à l'optimisation tardive d'une conception faible.

Une autre chose à considérer est la manière dont votre application évoluera dans le futur. Si vous considérez que votre code aura une longue durée de vie, optimiser les performances au stade de la conception est également une bonne idée.

D'après mon expérience, l'optimisation tardive fournit de maigres récompenses à un prix élevé. L’optimisation au stade de la conception, grâce à la sélection d’algorithmes et à l’ajustement, est bien meilleure. Le fait de savoir comment fonctionne votre code n’est pas un excellent moyen d’obtenir un code hautes performances, vous devez le savoir au préalable.

Shane MacLaughlin
la source
C'est certainement correct. J'imagine que l'optimisation prématurée survient lorsque le code est rendu plus complexe / difficile à comprendre pour des avantages peu clairs, d'une manière qui n'a qu'un impact local (la conception a un impact global).
Paul de Vrieze
2
Tout est une question de définitions. Je prends l'optimisation comme conception et écriture de code pour fonctionner de manière optimale. La plupart des gens ici semblent le traiter comme du piratage du code une fois qu'ils ont constaté qu'il n'est pas assez rapide ou efficace. Je passe beaucoup de temps à optimiser, généralement lors de la conception.
3
Optimiser la conception au début, Optimiser le code à la fin.
BCS
Vous avez tout à fait raison dans votre cas. Cependant, pour la plupart des programmeurs, ils pensent qu’ils auront des problèmes de performances, mais en réalité, ils ne le feront jamais. Beaucoup s’inquiètent des performances lorsqu’il s’agit de 1 000 entités, alors qu’un test de base des données montrerait que les performances sont satisfaisantes jusqu’à atteindre 1 000 entités.
Toby Allen
1
"La planification des performances optimales au stade de la conception est de loin supérieure à l'optimisation tardive d'une conception faible" et "l'optimisation tardive fournit de maigres récompenses à un prix élevé", très bien exprimé! Ce n'est probablement pas le cas pour 97% de tous les systèmes produits, mais c'est le cas pour beaucoup de systèmes - incroyablement nombreux.
Olof Forshell
10

En fait, j'ai appris que la non-optimisation prématurée est le plus souvent la racine de tout mal.

Lorsque des personnes écrivent un logiciel, il rencontrera d’abord des problèmes tels que l’instabilité, des fonctionnalités limitées, une mauvaise utilisation et des performances médiocres. Tous ces problèmes sont généralement corrigés lorsque le logiciel arrive à maturité.

Tous, sauf la performance. Personne ne semble se soucier de la performance. La raison est simple: si un logiciel tombe en panne, quelqu'un le corrigera et c'est tout, si une fonctionnalité est manquante, quelqu'un l'implémentera et le fera. Si le logiciel présente des performances médiocres, ce n'est souvent pas à cause d'une microoptimisation manquante. en raison de la mauvaise conception et personne ne va toucher à la conception du logiciel. DÉJÀ.

Regardez Bochs. C'est lent comme l'enfer. Cela ira-t-il un jour plus vite? Peut-être, mais seulement de l'ordre de quelques pour cent. Ses performances ne seront jamais comparables à celles d’un logiciel de virtualisation tel que VMWare, VBox ou même QEMU. Parce que c'est lent par conception!

Si le problème d'un logiciel est qu'il est lent, c'est parce qu'il est TRÈS lent et que cela ne peut être corrigé qu'en améliorant les performances d'une multitude. + 10% ne feront tout simplement pas un logiciel lent rapidement. Et vous n'obtiendrez généralement pas plus de 10% avec les optimisations ultérieures.

Donc, si les performances sont TOUTES importantes pour votre logiciel, vous devez en tenir compte dès le début, lors de la conception, au lieu de penser "ah oui, c'est lent, mais nous pouvons améliorer cela plus tard". Parce que tu ne peux pas!

Je sais que cela ne correspond pas vraiment à votre cas particulier, mais cela répond à la question générale "L'optimisation prématurée est-elle vraiment la racine de tout le mal?" - avec un NON clair.

Toute optimisation, comme toute fonctionnalité, etc. doit être soigneusement conçue et implémentée avec soin. Et cela inclut une évaluation appropriée des coûts et des avantages. N'optimisez pas un algorithme pour économiser quelques cycles ici et là, s'il ne crée pas un gain de performance mesurable.

À titre d’exemple, vous pouvez améliorer les performances d’une fonction en l’alignant, en économisant éventuellement quelques cycles, mais en même temps, vous augmentez probablement la taille de votre exécutable, ce qui augmente les risques de défaillances de TLB et de cache coûtant des milliers de cycles voire opérations de pagination, qui vont tuer complètement les performances. Si vous ne comprenez pas ces choses, votre "optimisation" peut s'avérer mauvaise.

Une optimisation stupide est plus diabolique qu'une optimisation "prématurée", mais les deux sont toujours mieux que la non optimisation prématurée.

moucheron
la source
6

PO pose deux problèmes: premièrement, le temps de développement utilisé pour un travail non essentiel pouvant être utilisé pour écrire plus de fonctionnalités ou pour corriger plus de bugs, et deuxièmement, le faux sentiment de sécurité selon lequel le code est exécuté efficacement. Le bon de commande implique souvent l'optimisation d'un code qui ne sera pas le goulot d'étranglement tout en ne remarquant pas le code qui le fera. Le bit "prématuré" signifie que l'optimisation est effectuée avant qu'un problème ne soit identifié à l'aide de mesures appropriées.

Donc, en gros, oui, cela ressemble à une optimisation prématurée, mais je ne la soutiendrais pas nécessairement sauf si cela introduisait des bogues - après tout, cela a été optimisé maintenant (!)

Harriyott
la source
Vous voulez dire "écrire plus de tests" au lieu de "écrire plus de fonctionnalités", non? :)
Greg Hewgill
1
plus de fonctionnalités, plus de tests :)
workmad3
Euh oui! C'est exactement ce que je voulais dire ...
harriyott
2
Le code introduit une complexité supplémentaire et ne sera probablement pas utilisé universellement. La sauvegarde (et des choses similaires) en dehors maintient le code propre.
Paul de Vrieze
3

Je crois que c'est ce que Mike Cohn appelle le code «plaqué or»: c’est-à-dire passer du temps sur des tâches qui pourraient être intéressantes mais qui ne sont pas nécessaires.

Il a déconseillé.

Le «placage d’or» du PS pourrait être une fonctionnalité très spécifique. Lorsque vous examinez le code, il prend la forme d'une optimisation inutile, de classes "évolutives", etc.

Ilya Kochetov
la source
2
Je pense que le "placage à l'or" est différent des optimisations. Les optimisations consistent généralement à essayer d’obtenir le maximum de performances, tandis que le «gold-plaquage» consiste à ajouter les «cloches et sifflets» (toutes les fonctionnalités supplémentaires) qui ne sont pas critiques pour le produit mais qui semblent / sont agréables à faire.
Scott Dorman
3

Comme il n’ya aucun problème à comprendre le code, ce cas peut être considéré comme une exception.

Mais en général, l'optimisation conduit à un code moins lisible et moins compréhensible et ne devrait être appliquée que lorsque cela est nécessaire. Un exemple simple - si vous savez que vous ne devez trier que quelques éléments - utilisez BubbleSort. Mais si vous pensez que les éléments pourraient augmenter et que vous ne savez pas dans quelle mesure, optimiser avec QuickSort (par exemple) n’est pas un mal, mais un must. Et cela devrait être pris en compte lors de la conception du programme.

m_pGladiator
la source
1
Ne suis pas d'accord Je dirais ne jamais utiliser une sorte de bulle. Quicksort est devenu un standard de facto et est bien compris. Il est aussi facile à mettre en œuvre qu’un tri en bulle dans tous les scénarios. Le plus petit commun dénominateur n’est plus aussi bas;)
1
Pour un très petit nombre d'éléments, la récursivité requise pour le tri rapide peut le ralentir, mais ... sans parler du fait qu'il est plus rapide dans le cas le plus défavorable du tri rapide (à savoir le tri rapide d'une liste triée)
workmad3
Oui, mais c'est juste un exemple sur la façon de sélectionner des algorithmes pour différents besoins;)
C'est vrai, mais j'utiliserais quicksort comme tri par défaut. Si je pensais que bubbleort améliorerait les performances, ce serait une optimisation et non l'inverse. Je choisis QuickSort par défaut car il est bien compris et généralement meilleur.
2
Mon idée d'un tri par défaut est celle que me donne la bibliothèque (qsort (), .sort (), (sort ...), peu importe).
David Thornley
3

J'ai constaté que le problème de l'optimisation prématurée se produit généralement lorsque la réécriture du code existant est plus rapide. Je peux voir à quel point l'écriture d'une optimisation compliquée pourrait poser problème, mais la plupart du temps, je vois une optimisation prématurée s'élever pour réparer ce qui n'est pas (connu pour être) brisé.

Et le pire exemple est lorsque je vois quelqu'un réimplémenter des fonctionnalités à partir d'une bibliothèque standard. C'est un drapeau rouge majeur. Par exemple, j'ai déjà vu quelqu'un implémenter des routines personnalisées pour la manipulation de chaînes, car il craignait que les commandes intégrées ne soient trop lentes.

Il en résulte un code plus difficile à comprendre (mauvais) et une perte de temps considérable sur un travail qui n’est probablement pas utile (mauvais).

jhocking
la source
3

D'un point de vue différent, mon expérience montre que la plupart des programmeurs / développeurs ne prévoient pas le succès et que le "prototype" devient presque toujours la version 1.0. J'ai une expérience directe de 4 produits originaux distincts dans lesquels une interface frontale élégante, sexy et très fonctionnelle (essentiellement l'interface utilisateur) a entraîné une adoption et un enthousiasme généralisés des utilisateurs. Dans chacun de ces produits, des problèmes de performances ont commencé à apparaître dans des délais relativement courts (1 à 2 ans), en particulier à mesure que des clients plus importants et plus exigeants commençaient à adopter le produit. Très vite, les performances ont dominé la liste des problèmes, bien que le développement de nouvelles fonctionnalités ait dominé la liste des priorités de la direction. Les clients devenaient de plus en plus frustrés à mesure que chaque version ajoutait de nouvelles fonctionnalités qui semblaient géniales mais étaient presque inaccessibles en raison de problèmes de performances.

Ainsi, des défauts de conception et de mise en œuvre très fondamentaux, peu ou pas préoccupants dans le "type prototype", sont devenus des obstacles majeurs au succès à long terme des produits (et des entreprises).

Votre démo client peut sembler très performante sur votre ordinateur portable avec des DOM XML, SQL Express et de nombreuses données en cache côté client. Le système de production plantera probablement une brûlure si vous réussissez.

En 1976, nous débattions encore sur les moyens optimaux de calculer une racine carrée ou de trier un grand nombre. L'adage de Don Knuth disait qu'il fallait se concentrer sur l'optimisation de ce type de routine de bas niveau au début du processus de conception plutôt que sur la résolution du problème. puis en optimisant les régions de code localisées.

Quand on répète l'adage comme une excuse pour ne pas écrire de code efficace (C ++, VB, T-SQL ou autre), ou pour ne pas concevoir correctement le magasin de données, ou pour ne pas prendre en compte l'architecture de travail réseau, alors IMO montre simplement une compréhension très superficielle de la nature réelle de notre travail. Rayon

Rayon
la source
1
Haha, ou lorsque la démo avec trois utilisateurs devient la version 1.0 avec mille.
Olof Forshell
1

Je suppose que cela dépend de la façon dont vous définissez le terme "prématuré". Rendre la fonctionnalité de bas niveau rapide lorsque vous écrivez n'est pas fondamentalement mauvais. Je pense que c'est un malentendu de la citation. Parfois, je pense que cette citation pourrait faire avec plus de qualification. Je ferais cependant écho aux commentaires de m_pGladiator sur la lisibilité.

Dominic Rodger
la source
1

La réponse est: ça dépend. Je soutiens que l'efficacité est un gros problème pour certains types de travail, tels que les requêtes de base de données complexes. Dans de nombreux autres cas, l'ordinateur passe le plus clair de son temps à attendre l'entrée de l'utilisateur. L'optimisation de la plupart des codes est au mieux une perte de temps et au pire une contre-production.

Dans certains cas, vous pouvez concevoir en fonction de l'efficacité ou de la performance (perçue ou réelle) - en sélectionnant un algorithme approprié ou en concevant une interface utilisateur afin que certaines opérations coûteuses soient effectuées en arrière-plan, par exemple. Dans de nombreux cas, le profilage ou d'autres opérations visant à déterminer les points chauds vous procurent un avantage de 10/90.

Un exemple de ceci que je peux décrire est le modèle de données que j'ai déjà utilisé pour un système de gestion d'instance comprenant environ 560 tables. Tout a commencé normalisé («magnifiquement normalisé» comme le dit le consultant d'une certaine entreprise big-5) et nous n'avons eu à y insérer que quatre données dénormalisées:

  • Une vue matérialisée pour supporter un écran de recherche

  • Une table maintenue par déclencheur pour prendre en charge un autre écran de recherche qui ne pouvait pas être créé avec une vue matérialisée.

  • Une table de rapport dénormalisée (cela n'existait que parce que nous devions traiter certains rapports de débit lorsqu'un projet d'entrepôt de données était mis en attente)

  • Une table maintenue par déclencheur pour une interface qui devait rechercher le plus récent parmi un assez grand nombre d'événements disparates dans le système.

C’était (à l’époque) le plus grand projet J2EE en Australasie - bien plus de 100 ans de temps de développement - et il y avait 4 éléments dénormalisés dans le schéma de base de données, dont un n’y appartenait pas vraiment.

Préoccupé parTonbridgeWells
la source
1

L'optimisation prématurée n'est pas la racine de TOUS les maux, c'est certain. Il y a cependant des inconvénients:

  • vous investissez plus de temps pendant le développement
  • vous investissez plus de temps à le tester
  • vous investissez plus de temps à réparer des bugs qui autrement ne seraient pas là

Au lieu d'une optimisation prématurée, on pourrait effectuer des tests de visibilité précoces afin de déterminer s'il était réellement nécessaire d'améliorer encore l'optimisation.

Herr_Alien
la source
1

La plupart de ceux qui adhèrent à "PMO" (la citation partielle, par exemple) disent que les optimisations doivent être basées sur des mesures et que celles-ci ne peuvent être effectuées qu'à la toute fin.

D'après mon expérience acquise dans le développement de grands systèmes, les tests de performance sont effectués à la toute fin, alors que le développement est presque terminé.

Si nous suivions les "conseils" de ces personnes, tous les systèmes seraient extrêmement lents. Ils seraient également coûteux, car leurs besoins en matériel sont beaucoup plus importants que prévu à l’origine.

Je préconise depuis longtemps de faire des tests de performance à intervalles réguliers dans le processus de développement: cela indiquera à la fois la présence d'un nouveau code (là où il n'y en avait pas auparavant) et l'état du code existant.

  • Les performances du code nouvellement implémenté peuvent être comparées à celles d'un code similaire existant. Une "impression" de la performance du nouveau code sera établie au fil du temps.
  • Si le code existant se déchaîne soudainement, vous comprenez que quelque chose lui est arrivé et vous pouvez le rechercher immédiatement, pas (beaucoup) plus tard, lorsque cela affecte l'ensemble du système.

Une autre idée favorite consiste à instrumenter un logiciel au niveau du bloc fonctionnel. Lors de son exécution, le système recueille des informations sur les temps d'exécution des blocs de fonction. Lorsqu’une mise à niveau du système est effectuée, il est possible de déterminer les blocs de fonction exécutés comme dans la version précédente et ceux qui se sont détériorés. Sur l'écran d'un logiciel, les données de performance sont accessibles à partir du menu d'aide.

Découvrez cet excellent article sur ce que le cabinet du premier ministre pourrait ou non vouloir dire.

Olof Forshell
la source