Ich las einen Artikel über schlechte Programmierpraktiken .
Es wurde erwähnt -
"Yo-Yo-Code", der einen Wert in eine andere Darstellung konvertiert und ihn dann wieder an die ursprüngliche Position zurücksetzt (z. B .: Konvertieren einer Dezimalzahl in eine Zeichenfolge und dann zurück in eine Dezimalzahl oder Auffüllen einer Zeichenfolge und anschließendes Zuschneiden)
Ich verstehe nicht, warum das besondere Beispiel, das er gibt, eine schlechte Art ist, Programme zu schreiben. Es scheint mir in Ordnung, zurück zu konvertieren, wenn die Situation dies erfordert, damit der Wert verwendet werden kann.
Kann mir jemand mehr darüber erklären?
programming-practices
anti-patterns
user13107
quelle
quelle
"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?
- Welche Situation wäre das?decimal myValue = decimal.Parse(dataReader["myColumn"].ToString())
ist ein Haustier Peeve von mir.Antworten:
Auch wenn Sie tun müssen sowohl die numerische als auch die Zeichenfolgendarstellung einer Zahl, ist es besser , nur einmal zu konvertieren und auch auf den ursprünglichen Wert hängen, anstatt wieder zu konvertieren jedes Mal , wenn der eine oder andere benötigen.
Das Prinzip ist, wie immer, dass Code, der nicht existiert, keine subtilen Mängel aufweisen kann , während Code, der oft existiert, dies tut. Das klingt vielleicht paranoid, aber die Erfahrung lehrt uns, dass es angebracht ist. Wenn Sie sich der Programmierung mit der permanenten Sorge nähern, "Ich bin nicht wirklich schlau genug, um dieses komplexe System zu verstehen", sind Sie auf dem richtigen Weg.
quelle
Es ist aus drei Hauptgründen schlecht:
Ich vermute, Grund 1 ist der Grund, an den Ihre Quelle aufgrund des Kontexts gedacht hat, in dem sie erwähnt wurde.
quelle
Ich würde die Beschreibung als "Code" umformulieren, der einen Typ in eine andere Darstellung umwandelt , um etwas zu tun, was im Original genauso gut oder besser hätte gemacht werden können, und es dann wieder zurück umwandeln andere Art, wirken auf mich, und sich zurück Umwandlung ist völlig angemessen und Versagen zu tun , würde zu falschem Verhalten so führen.
Ein Beispiel für eine gute Konvertierung:
Man hat vier
float
Werte von beliebigen Vorzeichen, deren Größen sich um einen Faktor von bis zu 1.000 unterscheiden können, und man muss die Summe zuletzt auf 0,625 Einheiten genau berechnen. Das Konvertieren aller vier Werte indouble
, das Berechnen der Summe und das Zurückkonvertieren des Ergebnisses infloat
ist wesentlich effizienter als dies bei einem Ansatzfloat
allein der Fall wäre .Gleitkommawerte sind bestenfalls auf 0,5 Einheiten (ULP) genau. Dieses Beispiel würde erfordern, dass der Worst-Case-Rundungsfehler nicht mehr als 25% über dem optimalen Worst-Case-Fehler liegt. Die Verwendung eines Doppels ergibt einen Wert, der innerhalb von 0,5001 ULP genau ist. Während eine ULP-Anforderung von 0,625 erfunden zu sein scheint, sind solche Anforderungen in sukzessiven Approximationsalgorithmen häufig wichtig. Je genauer die Fehlergrenze angegeben wird, desto geringer ist die Anforderung an die Iteration im ungünstigsten Fall.
Ein Beispiel für eine schlechte Konvertierung:
Man hat eine Gleitkommazahl und möchte einen String ausgeben, der seinen Wert eindeutig darstellt. Ein Ansatz besteht darin, die Zahl in eine Zeichenfolge mit einer bestimmten Anzahl von Ziffern zu konvertieren, sie zurück zu konvertieren und zu prüfen, ob das Ergebnis übereinstimmt.
Aber das ist eigentlich ein schlechter Ansatz. Wenn eine Dezimalzeichenfolge einen Wert darstellt, der fast genau auf dem halben Weg zwischen zwei Gleitkommawerten liegt, ist es für eine Zeichenfolge-zu-Gleitkomma-Methode ziemlich teuer, sicherzustellen, dass sie immer den näheren
float
Wert ergibt, und viele solche Konvertierungsmethoden geben keinen Wert an Halten Sie eine solche Garantie nicht ein (unter anderem würde dies in einigen Fällen das Lesen aller Ziffern einer Zahl erfordern, selbst wenn sie Milliarden von Ziffern lang wäre).Es ist viel billiger für eine Methode, zu garantieren, dass sie immer einen Wert zurückgibt, der innerhalb von 0,5625 Einheiten an der letzten Stelle (ULP) des dargestellten Werts liegt. Eine robuste "umkehrbare" Formatierungsroutine von Dezimal zu Zeichenfolge sollte berechnen, wie weit der Ausgabewert vom korrekten Wert entfernt ist, und die Ausgabe von Ziffern fortsetzen, bis das Ergebnis innerhalb von 0,375 (ULP) liegt, wenn nicht 0,25 (ULP). Andernfalls wird möglicherweise eine Zeichenfolge ausgegeben, die einige Konvertierungsmethoden ordnungsgemäß verarbeiten, andere Konvertierungsmethoden jedoch nicht.
Manchmal ist es besser, eine Ziffer auszugeben, die möglicherweise nicht "notwendig" ist, als einen Wert auszugeben, der möglicherweise falsch interpretiert wird. Entscheidend ist, dass die Entscheidung darüber, wie viele Ziffern ausgegeben werden sollen, auf numerischen Berechnungen im Zusammenhang mit dem Ausgabeprozess und nicht auf dem Ergebnis des Versuchs einer bestimmten Methode, die Zeichenfolge wieder in eine Zahl umzuwandeln, basiert.
quelle
Aus verschiedenen Gründen
Es ist sinnlos und erhöht die Komplexität - sowohl in Bezug auf die zu schreibende und zu wartende Codemenge als auch in Bezug auf die benötigte CPU-Zeit
Es kann an Genauigkeit verlieren oder den Wert komplett verfälschen
Es verschwendet Speicher (möglicherweise, abhängig von der Sprache), wenn Sie mehr Darstellungen einer Zahl speichern, die Sie benötigen
Es empfiehlt sich nur, die erste möglichst genaue Darstellung aller von Ihnen empfangenen Daten beizubehalten. Führen Sie mit diesen Daten Berechnungen durch und konvertieren Sie sie nur, wenn Sie sie ausgeben oder in einem besser lesbaren Format anzeigen müssen.
quelle
Warum? Denn auch die Besten von uns können Fehler machen.
Sehen Sie sich an, was passiert ist, als Microsoft versucht hat, ein Roundtrip-Format zu implementieren, um sicherzustellen, dass die Konvertierung von Float-Zeichenfolgen sicher ist: https://stackoverflow.com/q/24299692/541686
quelle
Als ich in der Schule war (und nach der Schule in der Elektrotechnik), wurde uns nach dem Multiplizieren das Teilen beigebracht. Division oft viele Ziffern und wird gerundet. Multiplikation nach Division multipliziert den Divisionsfehler.
Typkonvertierungen sind gleich, Sie laufen Gefahr, Daten zu verlieren. CInt (1,3) = 1.
In meiner Sprache, Basic, führen wir nur Typkonvertierungen durch (ein VB6-Programm verbringt 90% seiner Zeit mit der ANSI / Unicode-Konvertierung, für alle API-Aufrufe, die von der Laufzeit ausgeführt werden).
Die Typkonvertierung ist in allem, was wir tun, impliziert.
Die Zeichenfolge "5" wird aus dem numerischen Literal gedruckt.
Das Unicode-Zeichenfolgenliteral wird in eine ANSI-Zeichenfolge konvertiert und vom Formularpaket an SetWindowsTextA gesendet.
Auch das funktioniert in Basic
Ich bin heutzutage ein Variantenprogrammierer - ich denke nicht einmal an Typ. Ich verlasse mich nur auf die Autokonvertierungen.
Sowieso sind meine 3 Haustierhülsen
Zuweisen von Zeichenfolgenliteralen zu Variablen, um sie zu verwenden (verschwendet Speicher und Zeit)
Sinnlose Funktionen, wenn Code inline sein könnte (und der Compiler wird wahrscheinlich Ihre Funktion rückgängig machen und es trotzdem inline setzen)
Setzen Sie alle Objekte auf nichts als die letzten Zeilen vor einer End Function oder einem Programmende.
und ein viertes für Kurzprogramme
3 Variablen in einem 5-Zeilen-Programm sinnlos dimmen.
quelle