Je lisais un article sur les mauvaises pratiques de programmation .
Il a mentionné -
"Code Yo-Yo" qui convertit une valeur en une représentation différente, puis la reconvertit à son point de départ (par exemple: convertir une décimale en chaîne, puis la transformer en décimale, ou compléter une chaîne puis la couper)
Je ne comprends pas pourquoi l'exemple qu'il donne est un mauvais moyen d'écrire des programmes. Il me semble correct de reconvertir si la situation l'exige pour que la valeur puisse être utilisée.
Quelqu'un peut-il expliquer plus à ce sujet?
programming-practices
anti-patterns
utilisateur13107
la source
la source
"Roundabout code" that accomplishes in many instructions what could be done with far fewer (eg: rounding a number by converting a decimal into a formatted string, then converting the string back into a decimal)
.if the situation is so that they have to be used?
- quelle situation serait-ce?decimal myValue = decimal.Parse(dataReader["myColumn"].ToString())
est ma bête noireRéponses:
Même si vous avez besoin à la fois le numérique et la représentation de chaîne d'un nombre, il est préférable de convertir une seule fois et accrocher aussi à la valeur d' origine, au lieu de convertir à nouveau chaque fois que vous avez besoin d' un ou l'autre.
Le principe est, comme toujours, que le code qui n'existe pas ne peut pas avoir de défauts subtils , alors que le code qui existe en a souvent. Cela peut sembler paranoïaque, mais l'expérience nous enseigne que c'est approprié. Si vous abordez la programmation avec une légère anxiété permanente de "Je ne suis pas assez intelligent pour comprendre ce système complexe", vous êtes sur la bonne voie.
la source
C'est mauvais pour trois raisons principales:
Je soupçonne que la raison 1 est la raison à laquelle votre source pensait en fonction du contexte dans lequel elle a été mentionnée.
la source
Je reformulerais la description en "code qui convertit un type en une représentation différente dans le but de faire quelque chose qui aurait pu être fait aussi bien ou mieux dans l'original et le reconvertit ensuite. Il existe de nombreuses situations dans lesquelles convertir quelque chose en type différent, qui agissent sur lui, et de le convertir est de retour tout à fait approprié et non à faire serait donc entraîner un comportement incorrect.
À titre d’exemple où la conversion est bonne: on
a quatre
float
valeurs de signes arbitraires dont les grandeurs peuvent différer jusqu’à 1 000, et il faut calculer la somme à moins de 0,625 unité à la dernière place. Convertir les quatre valeurs endouble
, calculer la somme et reconvertir le résultat enfloat
sera beaucoup plus efficace que ne le serait toute approche utilisantfloat
seule.Les valeurs en virgule flottante sont au mieux précises à 0,5 unité à la dernière place (ULP). Cet exemple exigerait que l'erreur d'arrondi dans le cas le plus défavorable ne dépasse pas de plus de 25% l'erreur optimale dans le cas le plus défavorable. L'utilisation d'un double donnera une valeur précise à 0.5001 ULP. Bien qu'une exigence de 0,625 ULP puisse sembler artificielle, de telles exigences sont souvent importantes dans les algorithmes d'approximation successive. Plus la limite d'erreur est précise, plus l'exigence d'itération dans le pire des cas est faible.
À titre d’exemple où la conversion est mauvaise: l’
un a un nombre à virgule flottante et souhaite produire une chaîne qui représentera sa valeur de manière unique. Une approche consiste à convertir le nombre en une chaîne avec un certain nombre de chiffres, essayez de le reconvertir et de voir si le résultat correspond.
Mais c'est en fait une mauvaise approche. Si une chaîne décimale représente une valeur qui se situe presque exactement à mi-chemin entre deux valeurs à virgule flottante, il est assez coûteux pour une méthode chaîne-à-virgule de garantir qu'elle produira toujours le résultat le plus proche.
float
valeur , et beaucoup de ces méthodes de conversion ne maintenez pas une telle garantie (entre autres, cela nécessiterait dans certains cas de lire tous les chiffres d’un nombre, même s’il s’agissait de milliards de chiffres).Il est beaucoup moins coûteux pour une méthode de garantir qu'elle retournera toujours une valeur se situant à moins de 0,5625 unité à la dernière place (ULP) de la valeur représentée. Une routine de formatage "réversible" décimal en chaîne robuste doit calculer la distance entre la valeur de sortie et la valeur correcte et poursuivre la sortie de chiffres jusqu'à ce que le résultat se situe dans les limites de 0,375 (ULP) sinon de 0,25 (ULP). Sinon, il peut générer une chaîne que certaines méthodes de conversion traiteront correctement, mais d'autres méthodes de conversion ne le feront pas.
Il est préférable de produire parfois un chiffre qui pourrait ne pas être "nécessaire" que de produire une valeur qui pourrait être mal interprétée. L’essentiel est que le nombre de chiffres à produire soit déterminé en fonction de calculs numériques liés au processus de sortie, plutôt que du résultat de la tentative d’une méthode particulière de reconvertir la chaîne en nombre.
la source
Raisons diverses
C'est inutile et ajoute à la complexité - à la fois dans la quantité de code à écrire et à maintenir, et dans la quantité de temps CPU nécessaire
Il peut perdre en précision ou pire, corrompre entièrement la valeur
Cela gaspille de la mémoire (potentiellement, selon la langue) car vous finissez par stocker plus de représentations d'un nombre dont vous avez besoin
Une bonne pratique consiste à ne conserver que la première représentation, la plus précise possible, pour toutes les données que vous recevez. Effectuez tous les calculs à l'aide de ces données et ne les convertissez jamais que si vous devez les générer ou les afficher dans un format plus facile à lire.
la source
Pourquoi? Parce que même les meilleurs d'entre nous peuvent faire des erreurs.
Regardez ce qui s'est passé lorsque Microsoft a essayé d'implémenter un format "aller-retour" spécialement pour garantir la sécurité des conversions de chaînes flottantes <->: https://stackoverflow.com/q/24299692/541686
la source
Quand j'étais à l'école (et après l'école en génie électrique), on nous a appris à diviser après avoir multiplié. Division souvent beaucoup de chiffres et arrondis. Multiplier après division multiplie l'erreur de division.
Les conversions de types sont les mêmes, vous risquez de perdre des données. CInt (1.3) = 1.
Dans mon langage Basic, nous ne faisons que des conversions de types (un programme VB6 consacre 90% de son temps à la conversion ANSI / Unicode, pour tous les appels d'API effectués par le moteur d'exécution).
La conversion de type est implicite dans tout ce que nous faisons.
La chaîne "5" est imprimée à partir du littéral numérique.
Le littéral de chaîne unicode est converti en chaîne ANSI et envoyé à SetWindowsTextA par le package de formulaires.
Même cela fonctionne en base
Je suis un programmeur de variantes de nos jours - je ne pense même pas au type. Je me fie simplement aux autoconversions.
Quoi qu'il en soit mes 3 peeves sont
Assigner des littéraux de chaîne à des variables pour les utiliser (gaspillage de mémoire et lent)
Fonctions inutiles lorsque le code pourrait être en ligne (et le compilateur annulera probablement votre fonction et l'inline quand même)
Définir tous les objets à néant comme dernières lignes avant une fonction de fin ou une fin de programme.
et une 4ème pour les programmes courts
Variation inutile de vos 3 variables dans un programme de 5 lignes.
la source