Double.TryParse oder Convert.ToDouble - die schneller und sicherer?
Frage
Meine Anwendung liest eine Excel-Datei mit VSTO und fügt die gelesenen Daten an einem StringDictionary
. Es fügt nur Daten, die Zahlen mit wenigen Ziffern (1000 1000,2 1000,34 - Komma ist ein Trennzeichen in russischen Standards).
Was ist besser, zu prüfen, ob der aktuelle String eine entsprechende Anzahl ist?
object data, string key; // data had read
try
{
Convert.ToDouble(regionData, CultureInfo.CurrentCulture);
dic.Add(key, regionData.ToString());
}
catch (InvalidCastException)
{
// is not a number
}
oder
double d;
string str = data.ToString();
if (Double.TryParse(str, out d)) // if done, then is a number
{
dic.Add(key, str);
}
Ich habe StringDictionary
zu verwenden, anstatt Dictionary<string, double>
aufgrund der folgenden Parsing-Algorithmus Fragen.
Meine Fragen: Welcher Weg ist schneller? Welches ist sicherer?
Und ist es besser, zu nennen Convert.ToDouble(object)
oder Convert.ToDouble(string)
?
Lösung
Ich habe einen schnellen nicht-wissenschaftlichen Test in Release-Modus. Früher habe ich zwei Eingänge:. „2,34523“ und „badinput“ in beiden Methoden und iteriert 1.000.000 mal
Die gültige Eingabe:
Double.TryParse = 646ms
Convert.ToDouble = 662 ms
Nicht viel anders, als erwartet. Für alle Absichten und Zwecke, für die gültige Eingabe, dies ist die gleiche.
Ungültige Eingabe:
Double.TryParse = 612ms
Convert.ToDouble = ..
Nun .. es wurde für eine lange Zeit. Ich reran die ganze Sache mit 1.000 Iterationen und Convert.ToDouble
mit schlechten Eingang 8,3 Sekunden dauerte. Averaging es, wäre es mehr als 2 Stunden dauern. Mir ist es egal, wie grundlegende der Test, in dem ungültigen Eingabe Fall Convert.ToDouble
die Ausnahme Anhebung Ihre Leistung ruinieren.
So, hier ist eine andere Stimme für TryParse
mit einigen Zahlen um es wieder auf.
Andere Tipps
Mit zu beginnen, ich double.Parse
verwenden lieber als Convert.ToDouble
an erster Stelle.
Zur Frage, ob Sie Parse
oder TryParse
verwenden sollten: Sie vorgehen, wenn schlechte Eingangsdaten gibt es, oder ist das ein wirklich außergewöhnlich guter Zustand? Wenn es außergewöhnlich ist, verwenden Sie Parse
und lassen Sie es sprengen, wenn der Eingang ist schlecht. Wenn es erwartet wird und kann sauber gehandhabt werden, verwenden TryParse
.
Die .NET Framework-Design-Richtlinien empfehlen die Try-Methoden. Ausnahmen zu vermeiden, ist in der Regel eine gute Idee.
Convert.ToDouble(object)
tun ((IConvertible) object).ToDouble(null);
Welche Convert.ToDouble(string, null)
rufen
Es ist also schneller die String-Version zu nennen.
Allerdings ist die String-Version nur tut dies:
if (value == null)
{
return 0.0;
}
return double.Parse(value, NumberStyles.Float | NumberStyles.AllowThousands, provider);
Es ist also schneller die double.Parse
direkt zu tun.
Wenn Sie vorhaben, werden nicht die Ausnahme mit TryParse gehen Handhabung. TryParse ist schneller, weil es nicht mit dem ganzen Ausnahme-Stack-Trace zu befassen hat.
Ich versuche, im Allgemeinen die Convert
Klasse zu vermeiden (was bedeutet: Ich verwende es nicht), weil ich es sehr verwirrend finden: Der Code gibt zu wenige Hinweise auf das, was genau hier passiert, da Convert
viele semantisch sehr unterschiedliche Umwandlungen erlaubt treten mit dem gleichen Code. Dies macht es schwierig für den Programmierer zu kontrollieren, was genau passiert ist.
Mein Rat ist also nie diese Klasse zu verwenden. Es ist nicht wirklich notwendig, entweder (außer für binäre Formatierung einer Zahl, weil die normale ToString
Methode der Anzahl Klassen nicht geeignete Methode bieten, dies zu tun).
Wenn Sie nicht 100% sicher Ihre Eingaben sind, was selten der Fall ist, sollten Sie Double.TryParse verwenden.
Convert.ToDouble will throw an exception on non-numbers
Double.Parse will throw an exception on non-numbers or null
Double.TryParse will return false or 0 on any of the above without generating an exception.
Die Geschwindigkeit des Parse wird zweitrangig, wenn Sie eine Ausnahme auslösen, weil es nicht viel langsamer als die Ausnahme ist.
Viele Hass für die Convert-Klasse hier ... nur ein wenig zu balancieren, ist es ein Vorteil für Convert - wenn Sie ein Objekt übergeben,
Convert.ToDouble(o);
kann nur den Wert wieder ohne Probleme, wenn o ist bereits ein Doppelzimmer (oder ein int oder etwas leicht gießbaren).
Mit Double.Parse oder Double.TryParse toll ist, wenn Sie es bereits in einem String, aber
Double.Parse(o.ToString());
hat gehen machen die Zeichenfolge zuerst analysiert werden und je nach Eingabe, die teurer sein könnte.
Double.TryParse IMO.
Es ist einfacher für Sie zu behandeln, Sie wissen genau, wo der Fehler aufgetreten ist.
Dann können Sie damit umgehen, wie Sie sehen, passen, wenn es false zurück (d konnte nicht konvertieren).
Ich habe immer bevorzugt, die TryParse()
Methoden verwenden, weil es Erfolg oder Misserfolg wird, ohne sich um Ausnahmen zu kümmern zu konvertieren spucken zurück.
Ich persönlich finde die TryParse
Methode leichter zu lesen, die man Sie tatsächlich auf Ihrem Anwendungsfall abhängig verwenden werden soll: wenn Fehler können lokal behandelt werden Sie erwarten, Fehler und ein Bool von TryParse
ist gut, was Sie vielleicht möchten Sie nur die Ausnahmen fliegen lassen.
Ich würde erwarten, dass die TryParse
schneller zu sein, da sie den Aufwand für die Ausnahmebehandlung vermeidet. Aber verwenden Sie ein Benchmark-Tool, wie Jon Skeet MiniBench die verschiedenen Möglichkeiten zu vergleichen.
Dies ist eine interessante alte Frage. Ich füge eine Antwort, weil niemand ein paar Dinge mit der ursprünglichen Frage bemerkt.
Welche ist schneller: Convert.ToDouble oder Double.TryParse? Welches ist sicherer: Convert.ToDouble oder Double.TryParse
Ich werde diese beiden Fragen beantworten (Ich werde die Antwort aktualisieren später), im Detail, aber zuerst:
Zur Sicherheit das Ding alle Programmierer in dieser Frage verfehlt ist die Linie (Hervorhebung von mir):
Es fügt nur Daten, die Zahlen mit wenigen Ziffern (1000 1000,2 1000,34 - Komma ist ein Trennzeichen in russischen Standards ).
Gefolgt von diesem Codebeispiel:
Convert.ToDouble(regionData, CultureInfo.CurrentCulture);
Was hier interessant ist, dass, wenn die Tabellen in der russischen Zahlenformat sind aber Excel nicht korrekt die Zellenfelder eingegeben hat, was die richtige Interpretation der Werte kommen aus Excel?
Hier ist eine andere interessante Sache über die beiden Beispiele, in Bezug auf Geschwindigkeit:
catch (InvalidCastException)
{
// is not a number
}
Das wird wahrscheinlich MSIL generieren, die wie folgt aussieht:
catch [mscorlib]System.InvalidCastException
{
IL_0023: stloc.0
IL_0024: nop
IL_0025: ldloc.0
IL_0026: nop
IL_002b: nop
IL_002c: nop
IL_002d: leave.s IL_002f
} // end handler
IL_002f: nop
IL_0030: return
In diesem Sinne können wir wahrscheinlich die Gesamtzahl der MSIL Anweisungen vergleichen von jedem Programm durchgeführt -. Dazu später mehr als ich diesen Beitrag aktualisieren
Ich glaube, Code sollte richtig, klar sein und Fast ... In dieser Reihenfolge!