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 //pro Zeile ein Match
  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 //Startzeit, wir müssen einen neuen Eintrag anlegen
      entries.Add(id, new Entry(ID := id, StartTime := time));
    
    if name.StartsWith('Ende'and entries.ContainsKey(id) then //Endzeit, vorhandenen Eintrag im Dictionary mit Endzeit komplettieren
      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!