AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi Große strukturierte Textdateien laden - immer langsamer
Thema durchsuchen
Ansicht
Themen-Optionen

Große strukturierte Textdateien laden - immer langsamer

Ein Thema von friedemann2009 · begonnen am 20. Okt 2012 · letzter Beitrag vom 22. Okt 2012
Antwort Antwort
Seite 1 von 2  1 2      
nuclearping

Registriert seit: 7. Jun 2008
708 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#1

AW: Große strukturierte Textdateien laden - immer langsamer

  Alt 21. Okt 2012, 07:57
Ah, ok, jetzt verstehe ich das mal. Tja, in meinem Fall hätte ich keine Ahnung, wie ich da mit Pointern arbeiten soll -, dafür fehlt mir die Erfahrung.. Ich kannte Pointer bislang nur insofern, als damit ein Zeiger auf ein komplettes Datum (also z.B. eine Integer, ein String o.ä.) verschoben werden kann. Wie aber soll man *innerhalb* eines Datums (wie eine Textdatei) einen Zeiger verschieben? Habt Ihr da zufällig einen Link fürs erste Reinschauen zur Hand?

Danke und schöne Grüße,
frieder
Ist nicht so schwer, wie man sich das vielleicht denken mag.

Beispiel:
Delphi-Quellcode:
var
  MyString: String;
  MyPtr: Pointer;
begin
  MyString := 'Hallo Welt';
  GetMem(MyPtr, Length(MyString));
  try
    Move(MyString[1], MyPtr^, Length(MyString)); // "Hallo Welt" steht nun im Pointer
    
    Finalize(MyString);
    SetLength(MyString, 5);
    Move(MyPtr^, MyString[1], 5); // "Hallo" wird aus dem Pointer kopiert
  finally
    FreeMem(MyPtr);
  end;
end;
Oder:
Delphi-Quellcode:
var
  MyString: String;
  MyPtr: PChar;
  i, j: Integer;
  Found: Boolean;
begin
  MyString := '12345|Test';
  GetMem(MyPtr, Length(MyString));
  i := Integer(MyPtr); // Addresse vom Pointer merken
  try
    Move(MyString[1], MyPtr^, Length(MyString));
    Found := FALSE;
    j := 1;
    repeat
      if MyPtr^ = '|then
        Found := TRUE; // Trennzeichen gefunden, irgendwas machen
      Inc(MyPtr^);
      Inc(j);
    until Found or (j > Length(MyString));
  finally
    MyPtr := PByte(i); // Addresse vom Pointer wiederherstellen
    FreeMem(MyPtr);
  end;
end;
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#2

AW: Große strukturierte Textdateien laden - immer langsamer

  Alt 21. Okt 2012, 09:21
Na ja, Leute. Wenn mit 'Pointer' wirklich ein PChar gemeint ist, dann ist das 'Optimieren auf hohem Niveau'. Damit kann man sein Programm um einen Faktor X (so 10% schätze ich, von mir auch auch 20%) schneller machen. Auch der wirklich sinnvolle Hinweis, mit MMF einzulesen, bringt bei sehr großen Dateien eine drastische (aber konstante) Verbesserung (wieder um einen Faktor).

Hier geht es aber zunächst um das Verfahren. alsp das 'wie'. Die Vorredner haben hier Recht: Einen Parser kann man mit einer Komplexität von O(n) hinbekommen, d.h. er verhält sich von der Laufzeit so, das er bei einer Verdoppelung der Inputlänge auch nur doppelt so lange für die Verarbeitung braucht.

Dein Algorithmus scheint bei mindestens O(n^2) zu liegen (d.h. er vervierfacht die Zeit bei Verdopplung der Input-größe), aber wie sollen wir wissen, wie wir dir helfen können, wenn wir noch keine Zeile Code gesehen haben?


Praktisch "lade" ich so:
- Datei dekomprimieren
- Datei in Stringlist laden
- via Schleifen und Pos() die Tags einzeln suchen, größere Einheiten kopieren, Einzeldaten darin auswerten und je nach Datentyp in die jeweiligen Container (Array usw.) verschieben.
Der letzte Punkt dürfte der Entscheidende sein.

Geändert von Furtbichler (21. Okt 2012 um 09:29 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#3

AW: Große strukturierte Textdateien laden - immer langsamer

  Alt 21. Okt 2012, 09:53
Wie wäre es mit einer Verwaltungsstruktur am Anfang/Ende der Datei, oder in einer eigenen Datei, welche die Offsets,Länge und den Typ der Objekte beinhaltete. Die Objekte selbst werden dann gezielt per passendem Streamreader/writer geschrieben und gelesen?
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
10.113 Beiträge
 
Delphi 12 Athens
 
#4

AW: Große strukturierte Textdateien laden - immer langsamer

  Alt 21. Okt 2012, 10:06
Ist nicht so schwer, wie man sich das vielleicht denken mag.
Auweia, das ist aber auch bei weitem nicht so schwer wie du es jetzt gepostet hast.

Beispiel:
Delphi-Quellcode:
var
  MyString: String;
  MyPtr: PChar;
begin
  MyString := 'Hallo Welt';
  MyPtr := PChar(MyString);
  ShowMessage(Copy(MyPtr, 1, 5)); // 'Hallo'
  Inc(MyPtr, 6);
  ShowMessage(MyPtr); // 'Welt'
end;
Mit Inc und Zeichenzugriff via MyPtr^ lässt sich das bequem machen. Untypisiert mit dem Typ Pointer macht doch gar keinen Sinn...
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
nuclearping

Registriert seit: 7. Jun 2008
708 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#5

AW: Große strukturierte Textdateien laden - immer langsamer

  Alt 21. Okt 2012, 12:58
Auweia, das ist aber auch bei weitem nicht so schwer wie du es jetzt gepostet hast.
Es ging hauptsächlich darum, dem TE EINEN Weg zu zeigen, wie er mit Pointern und Strings arbeiten kann, ohne Copy, Pos, etc. zu verwenden.

Geändert von nuclearping (21. Okt 2012 um 13:00 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.745 Beiträge
 
Delphi 12 Athens
 
#6

AW: Große strukturierte Textdateien laden - immer langsamer

  Alt 21. Okt 2012, 10:11
Zitat:
Copy(MyPtr, 1, 5)
Copy arbeitet mit Strings, also wird der kompette PChar, bis zur nächsten #0 in einen String kopiert, dann davon via Copy ein Teil rauskpiert und zum Schluß der String wieder freigegeben.

Nimm da lieber SetString.


Beispiel:
Delphi-Quellcode:
var
  MyString: String;
  MyPtr: Pointer;
begin
  MyString := 'Hallo Welt';
  GetMem(MyPtr, Length(MyString));
  try
    Move(MyString[1], MyPtr^, Length(MyString)); // "Hallo Welt" steht nun im Pointer
    
    Finalize(MyString);
    SetLength(MyString, 5);
    Move(MyPtr^, MyString[1], 5); // "Hallo" wird aus dem Pointer kopiert
  finally
    FreeMem(MyPtr);
  end;
end;
...
Und jetzt haben wie wieder vergessen, daß es Unicode gibt und schon is der String futsch




Menno, ich finde es nicht mehr, aber ich dachte ich hätte mal eine Funktion gesehn (direkt im Delphi), welche einen String nimmt und einem daraus einen PChar erzeugt. Also das GetMem und Move direkt verbaut, wo man dann nicht an Unicode denken muß.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (21. Okt 2012 um 10:15 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.669 Beiträge
 
Delphi 12 Athens
 
#7

AW: Große strukturierte Textdateien laden - immer langsamer

  Alt 21. Okt 2012, 10:36
Meinst Du Delphi-Referenz durchsuchenStrPCopy?
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.745 Beiträge
 
Delphi 12 Athens
 
#8

AW: Große strukturierte Textdateien laden - immer langsamer

  Alt 21. Okt 2012, 13:58
Hab's gefunden (in falscher Unit gesucht )

Delphi-Referenz durchsuchenStrNew, welches man allerdings nur mit StrDispose wieder freigeben kann (es sei denn man rechnet die kranke Längenangabe raus)


Hmmm, nicht ganz ... das kopiert ja nur, aber reserviert keinen Speicher.
Ich mein eher sowas sie DupStr/StrDup aus C++.

Nja, aber StrLCopy (weil ja nicht der ganze String kopiert werden soll), zusammen mit einem GetMem würde sich gut in einer Funktion machen.

Delphi-Quellcode:
function DupStr(str: PAnsiChar; MaxLen: NativeInt = -1): PAnsiChar; override; // MaxLen incl. #0
function DupStr(str: PWideChar; MaxLen: NativeInt = -1): PWideChar; override;

function DupStr(str: PAnsiChar; MaxLen: NativeInt = -1): PAnsiChar;
begin
  if MaxLen = 0 then
    Exit(nil);
  if MaxLen < 0 then
    MaxLen = StrLen(str) + 1;
  Result := GetMemory(MaxLen * SizeOf(str^));
  try
    StrLCopy(Result, str, MaxLen);
  finally
    FreeMemory(P);
  end;
end;

function DupStr(str: PWideChar; MaxLen: NativeInt = -1): PWideChar;
...
Delphi-Referenz durchsuchenNewStr und Delphi-Referenz durchsuchenDispose für PChars (man darf nur nicht vergessen, daß Delphi dort noch eine Längenangabe drin versteckt)
Delphi-Referenz durchsuchenSetString = von PChar zu String
DupStr = von PChar/String zu PChar
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
friedemann2009

Registriert seit: 10. Feb 2010
49 Beiträge
 
#9

AW: Große strukturierte Textdateien laden - immer langsamer

  Alt 21. Okt 2012, 16:36
Abend zusammen,

wow, - da hab ich ja ne Diskussion losgetreten.. Vielen Dank für die vielen Anregungen! Ich versuche mal die Möglichkeiten für eine Optimierung zu sortieren:

- Ohne Pointer: soviel POS wie möglich raus, Stringlist möglichst nur einmal durchlaufen, ggf. kleinere Puffer bilden.

-> Das war bisher in etwa auch mein Ansatz. Das Problem ist dabei aber die Datencodierung a la 'Quasi'-XML, also mit Anfangs- und Endtag, fortlaufend, Baumstruktur. Bisher habe ich noch nicht mit fertigen XML-Parsern gearbeitet.

- Mit Pointern: Vielen Dank für die Code-Bsp. Ich muss aber leider gestehen, dass ich sie nicht wirklich verstehe. Mir ist wohl immer noch nicht die Logik klar, mit der man "Pointer verschieben" kann u.ä. Ohne Pointer, zB bei Strings ist mir klar: Ich kann mit einem Index und einem Count Teile eines Strings kopieren, löschen etc, quasi Intervalle herausschneiden und in einen neuen Topf gegeben und weiterverarbeiten. Wie soll das bei Pointern gehen? Wie kann ich da 'Intervalle' von Daten definieren, wenn ich doch nur mit EINEM Zeiger auf EINEN 'Punkt' (also z.B. eine ganze Variable im Speicher) verweise? Bräuchte ich - für Intervalle wie '234' in '12345' nicht zwei Pointer? Da steh ich aufm Schlauch..

- Streams: Das scheint mir die naheliegendste, weil auch gerade am einfachsten umzusetzende Lösung zu sein. Die Reihenfolge der Datenspeicherung/-ladung ist klar. Ob das dann wirklich schneller wird, weiß ich noch nicht. Muss ich ausprobieren. Es dürften damit aber einige POSes entfallen.

Falls noch jemand einen Tipp zum Pointer-Verständnis hat (gerne auch am Bsp. von jaenicke), würde ich mich freuen.

Ansonsten nochmal herzliches Dankeschön und einen schönen Sonntagabend wünscht Euch
frieder

Geändert von friedemann2009 (21. Okt 2012 um 16:49 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
10.113 Beiträge
 
Delphi 12 Athens
 
#10

AW: Große strukturierte Textdateien laden - immer langsamer

  Alt 21. Okt 2012, 19:39
Ja, du siehst das richtig was Pointer angeht. Ich habe z.B. immer einen Startpointer für den aktuellen Bereich und einen Laufpointer. Habe ich dann ein Element identifiziert, kopiere ich einfach ab dem Startpointer den String heraus. Die Länge bekomme ich durch die Differenz mit dem Laufpointer.

Auf diese Weise muss nur etwas kopiert werden, wenn ich auch etwas herauskopieren will.

Ein Beispiel kann ich erst morgen Abend liefern, wenn nötig.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:32 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz