Entwickler-Ecke
Basistechnologien - mit ReadLine Sprung zu Zeilennummer?
erther - Sa 20.03.10 23:49
Titel: mit ReadLine Sprung zu Zeilennummer?
Hallo,
ich hab folgendes Problem: Ich durchsuche eine txt Datei und muss zu einen Startwert den entsprechenden Endwert ermitteln. Beide haben in der gleichen Zeile die Zeit stehen, die ich dann beim Fund voneinander subtrahiere.
Momentan mache ich es so das ich die Datei Zeilenweise per ReadLine() auslese und einen counter mitlaufen lasse. Wenn der Startwert gefunden ist, lasse ich einen zweiten Readstream mit ReadLine() bis zur aktuellen counter Position in einer FOR Schleife vorlaufen und suche ab der Position dann meinen entsprechenden Endwert. Wenn der gefunden ist dann läuft mein erster ReadLine() weiter bis zum nächsten Startwert und das Spiel geht so weiter bis zum Ende der Datei.
Das ersichtliche Problem ist die Laufzeit, wenn ich erst jedesmal mit meinem zweiten ReadLine() von Dateianfang bis zur aktuellen counter Position vorlaufen muss. Meine Dateien die ich auswerten muss sind einige MB groß. Der Aufbau ist ungefähr so:
Quelltext
1: 2: 3: 4: 5: 6:
| Zeit Marke ID 12312 Start1 23 23342 Start2 342 32424 Start3 21 34556 Ende1 23 56543 Ende2 342 |
Leider scheint es keine Möglichkeit zu geben gleich in eine entsprechende Zeilennummer in einer Datei zu springen?! Wie kann ich die Suche beschleunigen?
Ich danke euch!!
Grüße!
erther
Greenberet - So 21.03.10 00:33
Lies die Datei einmal ein und speicher jeden eintrag in einer Liste und durchsuch dann die Liste
Christian S. - So 21.03.10 01:00
Ich denke, mit einem Dictionary kann man das gegenüber einer Liste nochmal beschleunigen:
Hab's mal in Delphi Prism gemacht:
Delphi-Prism-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| var entries := new Dictionary<Integer, Entry>; var matches := Regex.Matches(textInFile, '^(\d+)[ ]+([^ ]+)[ ]+(\d+)', RegexOptions.Multiline);
for m : Match in matches do begin var time := Int32.Parse(m.Groups[1].ToString); var name := m.Groups[2].ToString; var id := Int32.Parse(m.Groups[3].ToString); if name.StartsWith('Start') then entries.Add(id, new Entry(ID := id, StartTime := time)); if name.StartsWith('Ende') and entries.ContainsKey(id) then entries[id].EndTime := time; end; |
Dazu gehört noch eine Klasse "Entry" mit den Eigenschaft ID, StartTime und EndTime (alle Integer). Der Vorteil gegenüber einer Liste ist, dass die Suche des vorhandenen Eintrags im Dictionary sehr viel schneller ist.
erther - So 21.03.10 13:22
Hallo!
Danke für eure Antworten!
Ich hatte gestern Abend auch noch eine Eingebung und habs über ein ArrayList umgesetzt. Ich nehme an das ist das was Greenberet vorgeschlagen hat. Wenn das immer noch zu langsam ist schau ich mir die Dictionary Umsetzung näher an!
Schönen Tag euch!
Christian S. - So 21.03.10 13:26
ArrayList ist veraltet und sollte nicht mehr benutzt werden, benutze lieber eine generische Liste (also List<T>).
erther - So 21.03.10 14:53
Danke für den Tip!
Das Anwendungsprinzip scheint ja ähnlich des ArrayList zu sein. Wo liegen die Vorteile bzw. warum ist ArrayList veraltet?
Bin in der Programmierung nicht so drin, versuche aber beständig zu lernen! Darum danke für die Hilfe!
Christian S. - So 21.03.10 14:59
Die ArrayList verwaltet alles, was Du reinsteckst, als
Object.
Das heißt zum einen, dass wenn Du einen Valuetype (also z.B. Integer) reinsteckst, es zu
boxing bzw. unboxing [
http://openbook.galileocomputing.de/csharp/kap09.htm#t22] (letzteres beim Abrufen) kommt. Das ist performancemäßig nicht gut.
Zum anderen heißt es, dass Du die Typinformation verlierst. Du könntest in der ArrayList ja sogar Elemente verschiedenen Typs haben! Das führt am Ende nur zu Fehlern, vor allem aber auch zu unschönem Code, weil Du immer erst casten musst.
Bei einer
List<T> sparst Du Dir nicht nur das casten, sondern da sie die Typinformation enthält, hast Du alle Annehmlickeiten des IntelliSense oder auch
type inference [
http://de.wikipedia.org/wiki/Typinferenz].
erther - So 21.03.10 15:08
Nochmals danke!
Toll das einem hier so gut und schnell geholfen wird!
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!