Archiv für den Monat November 2011

Performance von SortedList und SortedDictionary


Wie bereits in meinem letzten Beitrag erwähnt habe ich ein kleines Tool zum Auswerten von Logdateien geschrieben und hier das erste mal so richtig gemerkt das es doch hin und wieder auf “Kleinigkeiten” und die Performance ankommt. Denn es ist schon ein Unterschied ob ich zum Laden und Auswerten eines Logfiles 20sek benötige oder zwei Minuten.

Im Letzten Beitrag ging es um die “DateTime.TrypParseExact” Methode welche für das einmalige Parsen eines Datumswertes problemlos funktioniert, aber wenn man zehntausende von Datensätzen laden möchte, ist sie ungeeignet, da sie zu langsam ist.

Ein weiteres Problem auf das ich gestoßen bin ist das Benutzen einer

SortedList<DateTime, CustomType>

wenn man mehr wie eine Million Datensätze in Ihr aufbewahrt. Denn aber ungefähr dieser Größenordnung habe ich feststellen müssen, das die SortedList nicht mehr Performant arbeitet. Hier hat das Hinzufügen neuer Werte plötzlich eine Zehntel Sekunde benötigt, was zu einer Ewigkeit werden kann wenn man fast 2 Millionen Einträge in der Liste hat.

Nachdem ich dann von der SortedList<DateTime, CustomType> auf ein SortedDictionary<DateTime, CustomType> umgestellt habe gingen auch Listen die mehr wie eine Million Einträge haben wieder sehr schnell zu laden. Wenn man also mit großen Datenmengen zu tun hat können sich schon einfache Umstellungen sehr stark auf die Performance auswirken, es lohnt sich also über alternative Listen und Funktionen zu informieren.

Performance von DateTime.TryParseExact


Ich habe in der letzten Woche ein kleines Tool zum Auswerten von Logdateien geschrieben und hier benötigte ich dringend die Möglichkeit ein bestimmtes Datum zu parsen damit ich jeweils eine Logzeile in meine Klassenstruktur bekomme.

Nichts leichter als das dachte ich mir und habe mich mal auf den .NET Datentyp DateTime und dessen Parse Methoden verlassen. Dazu habe ich mich dann für die “DateTime.TryParseExact” Methode entschieden um das passende Datum für das folgende Beispieldatum zu ermitteln “Tue Aug 09 19:23:14 2011”.

image

das ganze hat auch wunderbar geklappt und war nur ein kleiner Teil von dem was ich pro Zeile Parsen musste um meine Logfileklasse mit Daten zu füllen. Dann kam es zum ersten Versuch, das Einlesen eines 10.000 Zeilen langen Logfiles, was sage und schreibe rund 10 Sekunden in Anspruch nahm.

Nach reichlichem Suchen wo meine Zeit “verloren” geht habe ich die “DateTime.TryParseExact” Methode identifizieren können mit “System.Diagnostics.Stopwatch”.

Ich habe dann einfach mal für meinen speziellen Falle meine eigene “Parse” Methode geschrieben, welche auf das hier angegebene Datumsformat passt:

image

und trotz des “Umfangs” der Funktion war diese Version um den Faktor 100 Schneller, was man auch beim Einlesen des Logfiles merkte, dieses wurde jetzt quasi “Instant” geladen.

Ich hätte zu beginn nicht gedacht, das es an der “DateTime.TryParseExcact“ Methode liegt (p.s. ich habe auch die anderen Parse Methoden probiert von DateTime und alle waren so “langsam”) aber danach ist man immer schlauer. Also lieber einmal mehr schauen wo einem die Zeit “verloren” geht, denn man kann sich diese evtl. schneller wieder zurückholen als man denkt.