Cela fait quelques mois que j'ai commencé mon poste de développeur de logiciels d'entrée de gamme. Maintenant que j'ai dépassé certaines courbes d'apprentissage (par exemple le langage, le jargon, la syntaxe de VB et C #), je commence à me concentrer sur des sujets plus ésotériques, comme pour écrire de meilleurs logiciels.
Une question simple que j'ai posée à un collègue a été répondue par "Je me concentre sur les mauvaises choses". Bien que je respecte ce collègue, je ne suis pas d'accord que ce soit une «mauvaise chose» sur laquelle se concentrer.
Voici le code (en VB) et suivi de la question.
Remarque: La fonction GenerateAlert () renvoie un entier.
Dim alertID as Integer = GenerateAlert()
_errorDictionary.Add(argErrorID, NewErrorInfo(Now(), alertID))
contre...
_errorDictionary.Add(argErrorID, New ErrorInfo(Now(), GenerateAlert()))
J'ai écrit à l'origine ce dernier et l'ai réécrit avec le "Dim alertID" afin que quelqu'un d'autre puisse le lire plus facilement. Mais voici ma préoccupation et ma question:
Si l'on écrivait cela avec le Dim AlertID, cela prendrait en fait plus de mémoire; fini mais plus, et cette méthode devrait-elle être appelée plusieurs fois pourrait-elle conduire à un problème? Comment .NET va gérer cet objet AlertID. En dehors de .NET, il faut éliminer manuellement l'objet après utilisation (vers la fin du sous-marin).
Je veux m'assurer de devenir un programmeur compétent qui ne se fonde pas uniquement sur la collecte des ordures. Suis-je trop penser à cela? Suis-je en train de me concentrer sur les mauvaises choses?
Réponses:
"L'optimisation prématurée est la racine de tout mal (ou du moins la plupart) dans la programmation." - Donald Knuth
Quand il s'agit de votre premier passage, écrivez simplement votre code afin qu'il soit correct et propre. S'il est ultérieurement déterminé que votre code est critique en termes de performances (il existe des outils pour déterminer ce que l'on appelle des profileurs), il peut être réécrit. Si votre code n'est pas jugé critique pour les performances, la lisibilité est beaucoup plus importante.
Vaut-il la peine de creuser dans ces sujets de performance et d'optimisation? Absolument, mais pas sur le dollar de votre entreprise si cela n'est pas nécessaire.
la source
Pour votre programme .NET moyen, oui, c'est une réflexion excessive. Il peut y avoir des moments où vous voudrez en savoir plus sur ce qui se passe exactement à l'intérieur de .NET, mais cela est relativement rare.
L'une des transitions difficiles que j'ai eues a été de passer de l'utilisation de C et MASM à la programmation en VB classique dans les années 90. J'avais l'habitude d'optimiser tout pour la taille et la vitesse. J'ai dû abandonner cette pensée pour la plupart et laisser VB faire sa chose pour être efficace.
la source
Comme mon collègue disait toujours:
En d'autres termes, gardez toujours à l'esprit KISS (gardez-le simple stupide). Parce qu'une ingénierie excessive, une réflexion excessive sur la logique du code peut être un problème pour changer la logique la prochaine fois. Cependant, garder le code propre et simple est toujours une bonne pratique .
Cependant, avec le temps et l'expérience, vous sauriez mieux quel code sent et aurait besoin d'une optimisation très bientôt.
la source
La lisibilité est importante. Dans votre exemple , si, je ne suis pas sûr que vous vraiment faire des choses que plus lisible. GenerateAlert () a un bon nom et n'ajoute pas beaucoup de bruit. Il y a probablement de meilleures utilisations de votre temps.
Je suppose que non. C'est une optimisation relativement simple à réaliser pour le compilateur.
L'utilisation d'une variable locale comme intermédiaire n'a aucun impact sur le garbage collector. Si la mémoire haute de GenerateAlert () new, alors cela importera. Mais cela importera indépendamment de la variable locale ou non.
AlertID n'est pas un objet. Le résultat de GenerateAlert () est l'objet. AlertID est la variable qui, s'il s'agit d'une variable locale, est simplement un espace associé à la méthode pour garder une trace des choses.
Il s'agit d'une question plus délicate qui dépend du contexte impliqué et de la sémantique de propriété de l'instance fournie par GenerateAlert (). En général, tout ce qui a créé l'instance doit la supprimer. Votre programme serait probablement très différent s'il était conçu avec une gestion manuelle de la mémoire à l'esprit.
Un bon programmeur utilise les outils à sa disposition, y compris le garbage collector. Il vaut mieux penser à autre chose que vivre inconscient. Vous vous concentrez peut-être sur les mauvaises choses, mais puisque nous sommes ici, vous pourriez tout aussi bien en savoir plus.
la source
Faites-le fonctionner, rendez-le propre, rendez-le SOLIDE, PUIS faites-le fonctionner aussi vite qu'il le faut .
Cela devrait être l'ordre normal des choses. Votre toute première priorité est de faire quelque chose qui passera les tests d'acceptation qui secouent les exigences. C'est votre première priorité car c'est la première priorité de votre client; répondre aux exigences fonctionnelles dans les délais de développement. La prochaine priorité est d'écrire du code propre et lisible, facile à comprendre et qui peut ainsi être maintenu par votre postérité sans WTF lorsque cela devient nécessaire (il n'est presque jamais question de "si"; vous ou quelqu'un après vous devrez aller revenir et changer / réparer quelque chose). La troisième priorité est de faire adhérer le code à la méthodologie SOLID (ou GRASP si vous préférez), qui met le code en morceaux modulaires, réutilisables et remplaçables qui facilitent à nouveau la maintenance (non seulement ils peuvent comprendre ce que vous avez fait et pourquoi, mais il y a des lignes épurées le long desquelles je peux supprimer et remplacer chirurgicalement des morceaux de code). La dernière priorité est la performance; si le code est suffisamment important pour être conforme aux spécifications de performance, il est presque certainement assez important pour être rendu correct, propre et SOLIDE en premier.
Faisant écho à Christopher (et Donald Knuth), "l'optimisation prématurée est la racine de tout mal". De plus, le type d'optimisations que vous envisagez est à la fois mineur (une référence à votre nouvel objet sera créée sur la pile, que vous lui donniez un nom dans le code source ou non) et d'un type qui ne peut causer aucune différence dans la compilation IL. Les noms de variable ne sont pas reportés dans l'IL, donc puisque vous déclarez la variable juste avant sa première (et probablement seule) utilisation, je parierais de l'argent de la bière que l'IL est identique entre vos deux exemples. Ainsi, votre collègue a 100% raison; vous cherchez au mauvais endroit si vous cherchez une variable nommée vs une instanciation en ligne pour quelque chose à optimiser.
Les micro-optimisations en .NET n'en valent presque jamais la peine (je parle de 99,99% des cas). En C / C ++, peut-être, SI vous savez ce que vous faites. Lorsque vous travaillez dans un environnement .NET, vous êtes déjà suffisamment loin du métal du matériel pour qu'il y ait une surcharge importante dans l'exécution de code. Donc, étant donné que vous êtes déjà dans un environnement qui indique que vous avez renoncé à la vitesse fulgurante et que vous cherchez plutôt à écrire du code "correct", si quelque chose dans un environnement .NET ne fonctionne vraiment pas assez rapidement, sa complexité est trop élevé, ou vous devriez envisager de le paralléliser. Voici quelques conseils de base à suivre pour l'optimisation; Je vous garantis que votre productivité en optimisation (vitesse gagnée pour le temps passé) montera en flèche:
if(myObject != null && myObject.someProperty == 1)
), ou B prend plus de 9 fois plus de temps que A pour évaluer (if(myObject != null && some10SecondMethodReturningBool())
).la source
Le seul moment où vous devez vous soucier de l'optimisation dès le début, c'est lorsque vous savez que vous avez affaire à quelque chose d'énorme ou que vous savez qu'il s'exécutera un grand nombre de fois.
La définition de «énorme» varie évidemment en fonction de ce que sont vos systèmes cibles.
la source
Je préférerais la version à deux lignes simplement parce qu'il est plus facile de passer avec un débogueur. Une ligne avec plusieurs appels intégrés rend la tâche plus difficile.
la source