De nombreuses questions et réponses sur les pages C / C ++, traitent spécifiquement ou indirectement de problèmes de micro performance (tels que la surcharge d’une fonction indirecte vs directe ou directe), ou l’utilisation d’un algorithme O (N 2 ) vs O (N log N) sur une liste de 100 articles.
Je code toujours sans me soucier des micro-performances, et peu de préoccupations des macro-performances, en mettant l'accent sur un code facile à maintenir et fiable, à moins que ou jusqu'à ce que je sache que j'ai un problème.
Ma question est la suivante: pourquoi un grand nombre de programmeurs se soucient-ils autant? Est-ce vraiment un problème pour la plupart des développeurs, ai-je juste eu la chance de ne pas trop m'en inquiéter ou suis-je un mauvais programmeur?
la source
Réponses:
En pratique, la performance est rarement un problème qui nécessite une gestion aussi détaillée. Il vaut la peine de garder un œil sur la situation si vous savez que vous allez stocker et manipuler d'énormes quantités de données, mais sinon, vous avez raison et il est préférable de garder les choses simples.
L'un des pièges les plus faciles à tomber - en particulier en C et C ++, où vous avez un contrôle aussi fin - est l'optimisation trop tôt et à un niveau trop fin. En règle générale, la règle est la suivante: A) n'optimisez pas jusqu'à ce que vous sachiez que vous avez un problème, et B) n'optimisez rien de ce qui ne vous a pas été révélé problématique en utilisant un profileur.
Un corollaire à B) est le suivant: les programmeurs ont la réputation de ne pas savoir où se situent leurs goulots d’étranglement, même s’ils pensent que c’est bien. Utilisez un profileur et optimisez les composants lents ou modifiez les algorithmes si une section de code est appelée trop de fois, de sorte que cela pose un problème.
la source
./configure
, j'oserais dire que jusqu'à 75% du temps d'exécution peut être consacré à du code "d'initialisation" dans les programmes exécutés par le script. 25 à 50% pourraient même être dépensés en liens dynamiques.Je pense que tout sur votre liste est la micro-optimisation, qui ne devrait généralement pas être examinée, sauf pour
que je pense devrait être regardé. Bien sûr, cette liste contient 100 éléments pour le moment, et tout est rapide pour les petits n , mais je serais prêt à parier que ce même code sera réutilisé pour une liste de plusieurs millions de lignes et qu'il le sera toujours. travailler raisonnablement.
Choisir le bon algorithme n'est jamais une micro-optimisation. Vous ne savez jamais sur quels types de données le même code sera utilisé pendant deux mois ou deux ans plus tard. Contrairement aux "micro-optimisations" qui sont faciles à appliquer avec l'aide d'un profileur, les modifications apportées aux algorithmes nécessitent souvent une refonte importante pour une utilisation efficace des nouveaux algorithmes. (Par exemple, certains algorithmes exigent que les données d'entrée soient déjà triées, ce qui peut vous obliger à modifier des parties importantes de vos applications pour garantir que les données restent triées.)
la source
Il y a très peu de temps, dans mon premier emploi, j'avais écrit du code pour les systèmes embarqués. Ces systèmes utilisaient des microprocesseurs 8086 et avaient une mémoire limitée. Nous avons utilisé le compilateur Intel C. Un système que j'ai construit avait besoin d'accéder à un tableau 3D de structures. Je l'ai construit comme le livre me l'a dit: appelez malloc pour les 3 dimensions, puis allouez des lignes pour la dimension suivante, puis calloc pour les noeuds finaux.
C'était assez compliqué (pour moi à l'époque), je devais faire l'ajustement des courbes, le contrôle du processus ANOVA et l'analyse du chi carré. Aucune bibliothèque n’a fait cela pour nous; nous avons dû tout écrire et l’adapter au 8086.
Le système fonctionnait comme un chien. Après un rapide profilage, j'ai découvert que l'un des plus gros problèmes était l'allocateur. Pour résoudre le problème, j'ai abandonné tous les appels à malloc et procédé à ma propre gestion de la mémoire d'un gros bloc de mémoire.
Dans un autre cas concernant le même travail, le client se plaignait du temps de réponse de son système de contrôle de processus statistique. L'équipe avant moi avait conçu un système "logiciel PLC" dans lequel les opérateurs pouvaient utiliser une logique booléenne pour combiner des signaux et des commutateurs de déclenchement. Ils l'ont écrit dans un langage simplifié, ce que nous appellerions aujourd'hui un "langage spécifique à un domaine". comme je me souviens il ressemblait
((A1 + B1) > 4) AND (C1 > C2)
et ainsi de suite.La conception d'origine a analysé et interprété cette chaîne chaque fois qu'elle a été évaluée. Sur notre pauvre processeur, cela a pris beaucoup de temps et cela signifiait que le contrôleur de processus ne pouvait pas se mettre à jour aussi rapidement que le processus tournait.
J'y ai jeté un nouveau regard et ai décidé de traduire cette logique en code assembleur, au moment de l'exécution. Je l'ai analysé une fois , puis à chaque exécution, l'application a appelé une fonction générée dynamiquement. Un peu comme certains virus aujourd'hui, je suppose (mais je ne le sais pas vraiment). Le résultat a été multiplié par 100, ce qui a rendu le client et mon supérieur vraiment heureux.
Le nouveau code n'était pas aussi facile à gérer, étant donné que j'avais construit un compilateur personnalisé . Mais l’avantage de la performance l’emportait largement sur l’inconvénient de la maintenance.
Plus récemment, je travaillais sur un système qui devait analyser une mouche XML de manière dynamique. Les fichiers plus volumineux prendraient beaucoup plus de temps. C'était très sensible à la performance; trop lent d'une analyse, l'interface utilisateur deviendrait complètement inutilisable.
Ce genre de choses arrive tout le temps.
Donc, parfois, vous voulez du code facile à gérer, facile à écrire. Parfois, vous voulez un code qui s'exécute rapidement. Le compromis est la décision technique que vous devez prendre pour chaque projet.
la source
Si vous traitez des images volumineuses et que vous parcourez chaque pixel, il peut s'avérer crucial d'ajuster les performances.
la source
Laissez-moi vous parler un peu du pourquoi de cette culture.
Si vous êtes plus près de 40 que de 20 et que vous programmez votre vie à l'âge adulte, vous êtes devenu majeur lorsque C ++ était vraiment le seul jeu en ville, les applications de bureau étaient la norme et le matériel était encore logiciel très en retard en termes de capacités de bande passante / performances.
Très peu de gens ont à se soucier de ces choses aujourd'hui.
Cependant, il y a 10 ans, vous deviez toujours vous inquiéter du téléchargement de votre logiciel via un modem de 56 Ko et de son exécution sur un PC âgé de 5 ans ... Vous souvenez-vous à quel point les ordinateurs étaient de mauvaise qualité en 1996? Pensez en termes de 4 Go de disque dur, un processeur 200Mhz et 128 Mo de RAM ...
Et les serveurs d'il y a 10 ans? Le serveur "nouvelle génération" de Dell a coûté 2 000 dollars, et est livré avec 2 (!) Processeurs Pentium 1Ghz, 2 Go ou Ram et un disque dur de 20 Go.
C’était simplement un jeu de balle différent , et tous ces ingénieurs «expérimentés» qui ont 10 ans d’expérience (les gars susceptibles de répondre à vos questions) ont fait leurs armes dans cet environnement.
la source
Il y a déjà 10 réponses ici et certaines sont vraiment bonnes, mais parce que c'est une bête blanche pour moi ...
l'optimisation prématurée qui prend a) prend beaucoup plus de temps qu'une solution simple Cependant, si un développeur a le choix d'utiliser un std :: map ou un std :: vector et qu'il choisit la mauvaise collection par pure ignorance pour des performances aussi mauvaises sinon pires que l'optimisation prématurée. Et si vous pouviez légèrement modifier votre code aujourd'hui, maintenir la lisibilité, garder la même complexité, mais le rendre plus efficace, le feriez-vous? Ou appelleriez-vous cela "optimisation prématurée"? Je trouve que beaucoup de gens ne pensent même pas cela d'une manière ou d'une autre.
Auparavant, j'étais le type qui conseillait une "micro-optimisation" qui nécessitait très peu de changement et la même réponse que celle que vous venez de dire: "Vous ne devez pas optimiser trop tôt. Il suffit de le faire fonctionner et nous le changerons plus tard s'il y a un problème de performance ". Il a fallu plusieurs versions avant de le réparer. Et oui c'était un problème de performance.
Bien que l'optimisation initiale puisse ne pas être bonne, je pense qu'il est très bénéfique que les gens écrivent du code avec une compréhension de ce que ce code va faire et n'ignorent simplement pas les questions résultant de la notation O (x) en tant que "optimisation". Vous pouvez écrire beaucoup de code maintenant et, en réfléchissant un peu aux performances, évitez 80% des problèmes à venir.
Considérez également que de nombreux problèmes de performances ne vont pas se produire dans votre environnement et pas tout de suite. Il arrive parfois qu'un client repousse les limites ou qu'un autre développeur décide de créer au-dessus de votre infrastructure et d'augmenter le nombre d'objets de 10 fois. Avec certaines performances actuelles, vous pourriez éviter une nouvelle conception très coûteuse plus tard. Et si le problème est détecté après la publication officielle du logiciel, même un correctif simple devient 20 fois plus coûteux à appliquer.
En conclusion, garder toujours à l’esprit la performance aide à développer de bonnes habitudes. Ce qui est tout aussi important d’avoir une écriture propre, aussi simple que possible et organisée.
la source
Je soupçonne qu’une grande partie de ce que vous constatez est une simple erreur d’échantillonnage. Lorsque les gens traitent avec des situations simples, ils écrivent du code et c'est la fin des choses. Ils posent des questions lorsqu'ils traitent de problèmes relativement délicats, tels que la nécessité d'optimiser, en particulier dans une situation où l'optimisation n'est pas nécessairement évidente.
Cela dit, il y a sans aucun doute une optimisation prématurée en jeu également. Correctement ou non, C et C ++ ont la réputation d'être performants, ce qui a tendance à attirer les gens qui se soucient de la performance, y compris ceux qui peuvent faire de l'optimisation autant par plaisir que par nécessité.
la source
i++
ou non++i
operator ++
compilation n'a pas été effectuée.Quelques autres réponses mentionnent les systèmes embarqués , et j'aimerais développer davantage.
Il existe de nombreux dispositifs contenant des processeurs bas de gamme, par exemple: le contrôleur de chaudière de votre maison, une simple calculatrice de poche ou les dizaines de puces dans une voiture moderne.
Pour économiser de l'argent, ceux-ci peuvent avoir des quantités de mémoire flash (pour stocker du code) et de RAM qui semblent minuscules à ceux qui n'ont écrit que du code pour PC ou smartphones. Pour économiser de l'énergie, ils peuvent fonctionner à une fréquence d'horloge relativement faible.
Pour prendre un exemple, la famille de microcontrôleurs STM32 va de 24 MHz, 16 Ko en mémoire flash, 4 Ko de RAM , jusqu'à 120 MHz, 1 Mo en mémoire flash et 128 Ko de RAM .
Lorsque vous écrivez du code pour des puces comme celles-ci, vous gagnez beaucoup de temps si vous souhaitez que votre code soit aussi efficace que possible. De toute évidence, l'optimisation prématurée reste une mauvaise idée; mais avec de la pratique, vous apprendrez comment des problèmes courants peuvent être résolus rapidement et / ou avec un minimum de ressources, et codez en conséquence.
la source
Il s’agit essentiellement de langages de bas niveau. Lorsque l’on se heurte à un problème de performances pathologiques où un détail sans importance est à l’origine du goulot d’étranglement, on a en fait l’occasion de contourner le problème (plutôt qu'avec la plupart des autres). langues); mais bien sûr, souvent, comment le faire plus efficacement n’est pas immédiatement évident. D'où la moitié des questions de micro-optimisation étranges / intéressantes posées ici.
L'autre moitié vient de ceux qui sont curieux de savoir à quel point ils peuvent se rapprocher du métal. Ce sont essentiellement des langages de bas niveau, après tout ...
la source
Les performances sont toujours un sujet brûlant lorsque vous traitez en C et C ++. En ce qui concerne la distance à parcourir, vous pouvez toujours devenir fou au point d’intégrer l’ASM ou d’utiliser l’arithmétique de pointeur pour une itération plus rapide. Cependant, il arrive un moment où l’on consacre tellement de temps à optimiser que l’élaboration du programme global s’arrête.
Quand on traite de ces problèmes, il y a la performance du programmeur et celle du code. Laquelle de ces questions sur lesquelles on se concentrera posera toujours des questions intéressantes. En fin de compte, la question la plus importante est de savoir à quel point cela est perceptible pour l'utilisateur. L'utilisateur travaillera-t-il avec des données qui créent des tableaux avec des centaines ou des milliers d'éléments? Dans ce cas, le codage permettant d'accomplir des tâches rapidement peut amener l'utilisateur à se plaindre de la lenteur des opérations standard du programme.
Ensuite, il y a l'utilisateur qui travaillera avec de petites quantités de données. Quelques fichiers ici et là, où des opérations telles que le tri et les opérations sur les fichiers ne seront pas aussi perceptibles par l'utilisateur si vous utilisez des fonctions de niveau supérieur qui facilitent la maintenance au détriment de certaines performances.
Ceci est juste un petit exemple des problèmes que vous rencontrerez. Les autres problèmes incluent le matériel de l'utilisateur cible. Vous devrez vous soucier davantage de la performance si vous utilisez des systèmes embarqués, puis si vos utilisateurs disposent, par exemple, de machines à double cœur avec des concerts de RAM.
la source
Pourquoi les programmeurs se soucient-ils autant? Il y a des idées stupides qui peuplent leur esprit, telles que la résolution de problèmes de performance avant qu’ils ne sachent qu’ils les ont, et qu’ils ne comprennent pas quand ils devinent .
C'est délicat car, selon mon expérience, il y a des problèmes de performances auxquels il faut penser à l'avance. Il faut de l'expérience pour savoir ce qu'ils sont.
Cela dit, la méthode que j'utilise est semblable à la vôtre, mais pas la même.
Commencez avec la conception la plus simple possible. En particulier, la structure des données doit être aussi normalisée et minimale que possible. Dans la mesure où il y a une redondance inévitable, il convient d'éviter les notifications afin de les maintenir cohérentes. Il est préférable de tolérer une incohérence temporaire et de la réparer avec un processus périodique.
Lorsque le programme est en cours de développement, effectuez régulièrement des réglages de performances, car les problèmes de performances ont tendance à s’infiltrer. La méthode que j’utilise est la pause aléatoire , car je pense que c’est la meilleure solution .
Voici un exemple au coup par coup de ce que je veux dire.
la source
Pour être honnête, cela dépend de votre objectif et de la programmation que vous programmez de manière professionnelle ou personnelle.
De nos jours, les ordinateurs modernes sont des machines vraiment puissantes. Quelles que soient les opérations de base que vous décidez de faire, que vous essayiez ou non d'optimiser la micro-optimisation, elles peuvent effectuer leur travail de manière remarquablement rapide. Bien entendu, si vous faites autre chose (par exemple, la superinformatique pour des domaines tels que la physique ou la chimie), vous souhaiterez peut-être optimiser autant que vous le souhaitez.
Les premiers programmeurs du MIT n'étaient pas nés pour faire des choses géniales; Ils ont commencé à simplifier et à alimenter les algorithmes existants. Leur fierté était de faire en sorte que 2 + 2 donne quatre en deux secondes de moins que l'algorithme existant (ce n'est qu'un exemple, vous voyez l'idée). Ils ont constamment essayé d’utiliser moins de cartes perforées sur leurs TI-83 pour améliorer leurs performances.
De plus, si vous programmez des systèmes embarqués, vous devez certainement surveiller les performances micro. Vous ne voulez pas avoir une horloge numérique lente qui coche une seconde 5 nanosecondes plus tôt qu'une autre horloge numérique.
Enfin, si vous êtes un programmeur amateur, l'optimisation des moindres détails n'a aucun problème, même si votre programme est rapide, il l'est. Ce n'est pas nécessaire, mais vous pouvez y travailler et en profiter pour en apprendre davantage. Si vous travaillez de manière professionnelle dans un logiciel, vous ne pouvez prendre ce luxe que si cela est absolument nécessaire.
la source
J'étais dans une situation similaire récemment. J'ai eu un tableau d'éléments. Dans le cas attendu, il y avait deux (!) Éléments dans la liste, et même dans le pire des cas, je ne m'attends pas à plus de quatre, voire huit.
Je devais trier cette liste. En fin de compte, remplacer
std::sort
par un réseau de tri (essentiellement un grand nombre deif
s imbriqués ) réduisait un pourcentage important du temps d'exécution (je ne me souviens plus du nombre, mais il était de 10 à 20%). C'est un avantage énorme d'une micro-optimisation, et le code est absolument essentiel à la performance.Bien sûr, je ne l'ai fait qu'après le profilage. Mais le fait est que si j’utilise un langage aussi peu pratique et aussi compliqué que le C ++ (sans parler de ses règles extrêmement complexes en matière de résolution des surcharges), je souhaite en retirer tous les avantages.
la source
Consommation d'énergie cumulée
Il y a une réponse que je pense toujours qui manque dans cette discussion et qui me dérange un peu - la consommation d'énergie cumulative .
Bien sûr, peu importe si vous écrivez votre programme dans un langage interprété de haut niveau et le laissez s’exécuter dans un navigateur avec quelques couches d’indirection, ou si votre boucle prend 0,01 seconde au lieu de 0,001 seconde. Personne ne le remarquera, c'est-à-dire qu'aucun utilisateur ne le remarquera.
Mais lorsque des dizaines, voire des millions d’utilisateurs utilisent parfois votre code, toute cette inefficacité supplémentaire s’ajoute. Si votre outil empêche un processeur d'entrer dans l'état de veille pendant seulement dix secondes par jour et qu'un million d'utilisateurs l'utilisent, votre algorithme inefficace vient d'utiliser 140 kWh supplémentaires [1] par jour.
Je vois rarement cela discuté et je pense que c'est triste. Je soupçonne fortement que les chiffres sont bien pires pour les frameworks populaires, tels que Firefox, et les applications Web interactives sophistiquées, et il serait intéressant de faire une recherche.
[1] Je viens de raconter cela, 10 millions de secondes, 50 watts. Le chiffre exact dépend de beaucoup de choses.
la source
Parfois, vous avez juste des algorithmes qui ne peuvent pas être meilleurs que le temps linéaire pour lesquels il existe toujours une forte demande de performances.
Un exemple est le traitement vidéo où vous ne pouvez pas rendre une image / image plus claire en tant qu'exemple de base sans parcourir en boucle chaque pixel (eh bien, je suppose que vous pouvez utiliser une sorte de structure hiérarchique indiquant les propriétés héritées par les enfants qui finissent par descendre dans des mosaïques d'image. pour les nœuds feuilles, mais vous reporteriez alors un coût plus élevé de boucle sur chaque pixel pour le rendu et le code serait probablement plus difficile à maintenir que même le filtre d'image le plus micro-optimisé).
Il y a beaucoup de cas comme ça dans mon domaine. J'ai tendance à faire plus de boucles de complexité linéaire qui doivent tout toucher ou tout lire que celles qui bénéficient de tout type de structure de données ou d'algorithme sophistiqué. Il n'y a pas de travail qui peut être sauté quand tout doit être touché. Donc, à ce stade, si vous êtes inévitablement confronté à une complexité linéaire, vous devez rendre le travail effectué par itération moins cher et moins cher.
Donc, dans mon cas, les optimisations les plus importantes et les plus courantes sont souvent les représentations de données et les dispositions de mémoire, le multithreading et le SIMD (généralement dans cet ordre, la représentation des données étant la plus importante, car elle affecte la possibilité d'effectuer les deux dernières). Je ne rencontre pas tant de problèmes qui sont résolus par des arbres, des tables de hachage, des algorithmes de tri, etc. Mon code quotidien est plus dans la veine de "pour chaque chose, faire quelque chose."
Bien sûr, c’est un autre cas à prendre en compte lorsque des optimisations sont nécessaires (et plus important encore, lorsqu'elles ne le sont pas), micro ou algorithmiques. Mais dans mon cas particulier, si un chemin d’exécution critique doit être optimisé, les gains de vitesse 10x + sont souvent obtenus par des optimisations au niveau micro, telles que le multithreading, le SIMD et la réorganisation des configurations de mémoire et des modèles d’accès pour améliorer la localité de référence. Par exemple, il m'est moins fréquent de remplacer un type de bulle par un type introsort, un type de base ou une détection de collision à complexité quadratique par un BVH, que de rechercher des points chauds bénéficiant, par exemple, du découpage en champs chaud / froid.
Maintenant, dans mon cas, mon domaine est tellement critique en termes de performances (lancer de rayons, moteurs physiques, etc.) qu’un traceur de rayons lent mais parfaitement correct nécessitant 10 heures pour restituer une image est souvent considéré comme inutile ou plus qu'un rapide qui est complètement interactif, mais génère les images les plus laides avec des rayons qui fuient partout en raison de l'absence d'intersection rayon / tri étanche. La vitesse est sans doute la principale mesure de qualité d'un tel logiciel, sans doute même plus que la correction à un moment donné (puisque la "correction" est une idée floue avec le lancer de rayons puisque tout se rapproche, du moment qu'il ne s'écrase pas ou quelque chose comme ça). Et lorsque c'est le cas, si je ne pense pas à l'efficacité dès le départ, je me trouve dans l'obligation de modifier le code au niveau de conception le plus coûteux pour gérer des conceptions plus efficaces. Donc si je ne le fais pas
Le jeu est un autre domaine similaire au mien. Peu importe si votre logique de jeu est correcte ou si votre base de code est maintenable et brillamment conçue, si votre jeu fonctionne à 1 image par seconde, comme un diaporama. Dans certains domaines, le manque de rapidité pourrait en réalité rendre l'application inutilisable pour ses utilisateurs. Contrairement aux jeux, il n'existe pas de métrique "assez bonne" dans des domaines tels que le lancer de rayons. Les utilisateurs veulent toujours plus de vitesse et la concurrence industrielle cherche principalement à trouver des solutions plus rapides. Ce ne sera jamais assez bon jusqu'à ce que ce soit en temps réel, à quel moment les jeux utiliseront des traceurs de chemins. Et puis, cela ne sera probablement toujours pas suffisant pour les effets spéciaux, car les artistes voudront peut-être charger des milliards de polygones et effectuer des simulations de particules avec auto-collision entre des milliards de particules à plus de 30 FPS.
Maintenant, si cela peut vous rassurer, malgré tout, j’écris environ 90% du code dans un langage de script (Lua) sans me soucier de la performance. Mais j'ai une quantité inhabituellement importante de code qui doit parcourir des millions, voire des milliards de choses, et lorsque vous passez en revue des millions, voire des milliards de choses, vous commencez à remarquer une différence épique entre le code naïf à un seul thread: invoque un cache cache à chaque itération, par opposition à un code vectorisé s'exécutant en parallèle et accédant à des blocs contigus dans lesquels aucune donnée non pertinente n'est chargée dans une ligne de cache.
la source
Comme vous l'avez mentionné, il est inutile de se préoccuper des problèmes de performance micro avant de prendre en compte certains problèmes réellement causés par ces problèmes.
la source
Il est vraiment impossible de répondre à cette question en général. La plupart des logiciels en cours de construction sont des sites Web internes et des applications métier. Pour ce type de programmation, votre raisonnement est tout à fait correct. D'un autre côté, si vous écrivez quelque chose comme un pilote de périphérique ou un moteur de jeu, aucune optimisation n'est "prématurée"; il est probable que votre logiciel fonctionnera sur des systèmes très différents avec des contraintes matérielles différentes. Dans ce cas, vous devez optimiser les performances et vous assurer de ne pas choisir un algorithme sous-optimal.
la source
Je pense que le problème du programmeur, qui se préoccupe tellement de la performance, est que parfois, dans sa vie, il devait écrire un code extrêmement performant, peut-être de toute urgence, et il a appris, appris, appris et finalement beaucoup de choses et astuces.
Et maintenant, il est difficile d’oublier, et sans mesure préalable, ce qui montre qu’il n’a pas à s’inquiéter, il est du côté de la sécurité, utilisant un code rapide.
Il est toujours agréable de montrer vos connaissances approfondies, vos compétences et quelques astuces, et de réutiliser quelque chose que vous avez appris. Vous vous sentez précieux et le temps que vous passez à apprendre vaut la peine.
Parfois, dans ma vie, j'ai appris que l'incrément de préfixe est plus rapide ...
... que l'incrément postfix:
Maintenant, si MAX est bas, ce ne sera pas grave, et s'il y a du vrai travail dans la boucle, ce ne sera pas grave non plus. Mais il n’ya aucune raison d’utiliser la version postfix, même si aujourd’hui le compilateur optimise lui-même le code.
Peut-être que ceux qui recherchent la performance ont besoin d'un objectif supplémentaire, en plus de l'écriture de «code de travail», tel que «code de travail et lisible», pour avoir une ligne de conduite dans le grand océan d'options.
la source
Vous souciez-vous de vos besoins? Si les performances ne sont pas une exigence, ne vous inquiétez pas. Consacrer du temps à cela est un mauvais service pour votre employeur.
Dans une certaine mesure, la performance est toujours une exigence. Si vous pouvez le frapper sans y penser, vous êtes en droit de ne pas y penser.
Personnellement, je suis le plus souvent motivé par la performance lorsque mes tests sont trop longs à passer. Je suis trop impatient d'attendre 5 minutes pendant qu'une série de tests réussissent. Mais cela est généralement résolu en manipulant les tests.
Il y a un grand nombre de programmeurs qui sont justifiés dans combien ils se soucient. Il y en a beaucoup qui ne le sont pas. Parlons de ceux qui ne le sont pas.
L’une des premières choses que les programmeurs apprennent à l’école, après avoir fait fonctionner les choses, est la grande notation O. Bon nombre d’entre eux apprennent la leçon correctement et se concentrent donc correctement sur des choses radicalement touchées par n. D'autres ne comprennent pas les calculs et ne retiennent que la leçon selon laquelle, une fois que cela fonctionne, il faut être rapide. Pire encore, certains de ces étudiants n'apprennent jamais rien de ce qui est important à faire avec votre code, à part le faire fonctionner rapidement. Les leçons manquées: rendez-les lisibles, concevez-les bien, n'y jouez pas sans raison.
Knuth avait raison: l'optimisation prématurée est la racine de tout mal. Mais une fois que cela fonctionne, quelle est la prochaine étape? Rapide non? NON! La prochaine étape est lisible. Lisible est la première, la prochaine, la seconde et la deuxième étape. La plupart des gens que je trouve en train d’optimiser des performances inutiles jettent la lisibilité sous le bus.
Certains ressentent même un frisson pervers dû à leur code illisible. Ils ont du mal à comprendre le code créé par d’autres, alors c’est maintenant à leur tour de payer.
Je le sais parce que je le faisais auparavant. Une fois, j'ai refactoré une ligne parfaitement lisible si la structure était réduite à une expression booléenne d'une ligne indéchiffrable et je l'ai fièrement envoyée à mon professeur dans l'espoir de faire bonne impression, car je pouvais créer quelque chose d'aussi compact et intimidant. Je n'ai pas eu l'éloge que j'espérais.
Si le code reste lisible, le rendre rapide plus tard est facile. C'est pourquoi Knuth insiste sur le terme "prématuré" et non "inutile". Parce que bien sûr, mieux c'est, plus vite. Mais mieux vaut mieux que dépendre de ce que vous sacrifiez pour cela. Attendez donc de savoir de quelle performance vous avez vraiment besoin avant de faire des sacrifices pour cela. Sacrifiez à contrecœur la lisibilité, car une fois qu'il est parti, il est difficile de revenir.
Au-delà de la lisibilité, le monde entier de la conception de logiciels. De quoi parle ce site Certains n'ont aucune idée de ce qu'il faut faire en matière de design. Donc, comme ils ne peuvent pas impressionner par le design, ils créent un gâchis indéchiffrable afin que les gens ne puissent pas dire qu'ils n'en ont aucune idée. Puisque personne ne répare jamais leur code, ce doit être un bon code, non?
Pour certains, la performance est l'excuse idéale pour faire ce qu'ils veulent. Les programmeurs ont beaucoup de pouvoir et d’autonomie. La confiance a été mise en eux. Ne pas abuser de la confiance.
la source