Frage

Ich weiß viel über die verschiedenen Möglichkeiten des Umgangs mit Text für Informationen Parsen. Für ganze Zahlen zum Beispiel des Parsen, welche Art von Leistung zu erwarten. Ich frage mich, wenn jemand eine gute Werte auf diese kennt. Ich suche für einige reelle Zahlen von jemandem, der diese getestet hat.

Welche dieser bietet die beste Leistung in welchen Situationen?

Parse(...)  // Crash if the case is extremely rare .0001%

If (SomethingIsValid) // Check the value before parsing
    Parse(...)

TryParse(...) // Using TryParse

try
{
    Parse(...)
}
catch
{
    // Catch any thrown exceptions
}
War es hilfreich?

Lösung

Immer T.TryParse (string str, aus T-Wert) . Ausnahmen ist teuer und sollte Werfen vermieden werden, wenn man mit der Situation umgehen können a priori . Mit Hilfe eines Try-Catch-Block zu „retten“ auf die Leistung (weil Ihre ungültige Datenrate niedrig ist) ist ein Missbrauch der Ausnahme auf Kosten der Wartbarkeit Handhabung und gute Programmierpraktiken. Folgen Sie Sound-Software Engineering Entwicklungspraktiken, schreiben Sie Ihre Testfälle, führen Sie Ihre Anwendung, DANN Benchmark und optimieren.

  

„Wir sollten über kleine Effizienz, sagen sie etwa 97% der Zeit vergessen: vorzeitige Optimierung ist die Wurzel aller Übel Und doch sollten wir unsere Chancen in diesem kritischen 3% nicht verzichten.“ - Donald Knuth

Zu diesem Zweck ordnen Sie, willkürlich wie in Emissionszertifikaten, dass die Leistung von Try-Catch ist schlechter und dass die Leistung von TryParse ist besser . Erst nachdem wir unsere Anwendung und bestimmt ausgeführt haben, dass wir eine Art Verlangsamung w.r.t. haben String-Parsing würden wir sogar überlegen, etwas anderes als TryParse verwendet wird.

(edit: da es der Frages erscheint wollte Zeitdaten mit guten Ratschlägen zu gehen, hier ist die Zeitdaten angefordert)

Die Zeiten für verschiedene Ausfallraten auf 10.000 Eingaben vom Benutzer (für die Ungläubigen):

Failure Rate      Try-Catch          TryParse        Slowdown
  0%           00:00:00.0131758   00:00:00.0120421      0.1
 10%           00:00:00.1540251   00:00:00.0087699     16.6
 20%           00:00:00.2833266   00:00:00.0105229     25.9
 30%           00:00:00.4462866   00:00:00.0091487     47.8
 40%           00:00:00.6951060   00:00:00.0108980     62.8
 50%           00:00:00.7567745   00:00:00.0087065     85.9
 60%           00:00:00.7090449   00:00:00.0083365     84.1
 70%           00:00:00.8179365   00:00:00.0088809     91.1
 80%           00:00:00.9468898   00:00:00.0088562    105.9
 90%           00:00:01.0411393   00:00:00.0081040    127.5
100%           00:00:01.1488157   00:00:00.0078877    144.6


/// <param name="errorRate">Rate of errors in user input</param>
/// <returns>Total time taken</returns>
public static TimeSpan TimeTryCatch(double errorRate, int seed, int count)
{
    Stopwatch stopwatch = new Stopwatch();
    Random random = new Random(seed);
    string bad_prefix = @"X";

    stopwatch.Start();
    for(int ii = 0; ii < count; ++ii)
    {
        string input = random.Next().ToString();
        if (random.NextDouble() < errorRate)
        {
           input = bad_prefix + input;
        }

        int value = 0;
        try
        {
            value = Int32.Parse(input);
        }
        catch(FormatException)
        {
            value = -1; // we would do something here with a logger perhaps
        }
    }
    stopwatch.Stop();

    return stopwatch.Elapsed;
}

/// <param name="errorRate">Rate of errors in user input</param>
/// <returns>Total time taken</returns>
public static TimeSpan TimeTryParse(double errorRate, int seed, int count)
{
    Stopwatch stopwatch = new Stopwatch();
    Random random = new Random(seed);
    string bad_prefix = @"X";

    stopwatch.Start();
    for(int ii = 0; ii < count; ++ii)
    {
        string input = random.Next().ToString();
        if (random.NextDouble() < errorRate)
        {
           input = bad_prefix + input;
        }

        int value = 0;
        if (!Int32.TryParse(input, out value))
        {
            value = -1; // we would do something here with a logger perhaps
        }
    }
    stopwatch.Stop();

    return stopwatch.Elapsed;
}

public static void TimeStringParse()
{
    double errorRate = 0.1; // 10% of the time our users mess up
    int count = 10000; // 10000 entries by a user

    TimeSpan trycatch = TimeTryCatch(errorRate, 1, count);
    TimeSpan tryparse = TimeTryParse(errorRate, 1, count);

    Console.WriteLine("trycatch: {0}", trycatch);
    Console.WriteLine("tryparse: {0}", tryparse);
}

Andere Tipps

Auch wenn ich persönlich habe nicht die verschiedenen Möglichkeiten, profiliert, dieser Typ hat:

http://blogs.msdn.com/ianhu /archive/2005/12/19/505702.aspx

Try-Catch immer die langsamer. TryParse wird schneller sein.

Die IF und TryParse gleich sind.

Hier ist ein anderer Kerl, der die Leistungsunterschiede ist auch profilierte , und tut dies mit einem paar verschiedenen Datentypen zu sehen, wie viel (wenn überhaupt) sie von Natur aus der Leistung beeinflussen: int, bool, und Datetime.

Option 1: Will throw an exception on bad data.
Option 2: SomethingIsValid() could be quite expensive - particularly if you are pre-checking a string for Integer parsability.
Option 3: I like this.  You need a null check afterwards, but it's pretty cheap.
Option 4 is definitely the worst.

Die Ausnahmebehandlung ist vergleichsweise teuer, so vermeiden Sie es, wenn Sie können.

Insbesondere schlechte Eingänge zu erwarten sind, nicht außergewöhnlich, so sollten Sie sie nicht für diese Situation nutzen.

(Obwohl, vor TryParse, kann es die beste Option gewesen sein.)

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