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)?

War es hilfreich?

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!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top