![]() |
Routine dauert ewig
Hallo,
ich bin fast am Verzweifeln. Ich versuche den Inhalt einer simplen Binärdatei zu lesen, was aber ewig dauert. Hier ist der Code.
Delphi-Quellcode:
Die Funktion wird ca. 20xmal aufgerufen. Wenn ich Showmessage weglasse, dann dauert die Schleife ewig. Lasse ich eine Meldung einblenden, geht es in einer ganz normalen Geschwindigkeit. An was kann das liegen?
function LiesEineBinaerDatei(ASpecialFile: String) : WideString;
var wHeader, wHeader2 : Word; i, dez : integer; TMStream : TMemorystream; begin Result := ''; TMStream := TMemoryStream.Create; TMStream.LoadFromFile(ASpecialFile); try TMStream.Seek(16, soFromBeginning); for i := 0 to 47 do begin TMStream.Read(wHeader, 2); TMStream.Read(wHeader2, 1); dez := wHeader + wHeader2 * 256; Result := Result + WideChar(dez); end; // Showmessage(Result); finally TMStream.Free; end; end; Danke für jeden Hinweis Amigage |
Re: Routine dauert ewig
daran:
Delphi-Quellcode:
Das ist das schlimmste was du dem Speicher antun kannst.
Result := Result + WideChar(dez);
Du weißt das Result am Ende eine Größe von "28 * SizeOf(WideChar)" hat. Also setze result gleich auf diese Größe um zu vermeiden das der Speicher jedes mal neu reserviert und umkopert werden muss. :-D |
Re: Routine dauert ewig
aber das erklärt noch nicht das Phänomen das es mit showmessage schneller läuft als ohne, oder?
|
Re: Routine dauert ewig
wie hast du ermittelt das es mit ShowMessage schneller läuft? Mit ShowMessage musst du ja erst die Message weg klicken wodurch das ganze subjektiv wird. Zudem kann durch die Verwendung von ShowMessage die Speicherfraktierung anders aussehen.
Liest du immer wieder die gleiche Datei oder immer eine andere? |
Re: Routine dauert ewig
Wie groß ist eigentlich die Datei?
TMemoryStream ließt ja erstmal die ganze Datei ein, selbst wenn nur das Stückchen am Anfang gebraucht wird. Zur Zeitmessung: wie schon gesagt, wie hast du den Unterschied festgestellt? hast du bedacht, daß die Datei beim einlesen in der Windows-FileCache landet und demnach eim nächsten Mal eventuell wesendlich schneller geladen werden könnte? (solange du die FileCache vorher nicht jedesmal in einen definierten/gleichwertigen Zustand versetzt) [add] :warn: ist dir aufgefallen, daß das HiByte von wHeader2 undefiniert ist? Dieses ist ja ein Word und Write ließt nur 1 Byte (in das LoByte). u solltest also vor der Schleife wHeader2 in einen definierten Zustand bringen (z.B. wHeader2 := 0; ).
Delphi-Quellcode:
(ich hoff ich hab's richtig übersezt)
Var F: File of Byte;
Buf: Array[0..48*3-1] of Byte; W: Integer; Begin AssignFile(F, ASpecialFile); Try FileMode = fmOpenRead; Reset(F); Seek(F, 16); BlockRead(F, Buf, SizeOf(Buff), W); If W = SizeOf(Buf) Then Begin SetLength(Result, 48); For i := 0 to 47 do //Result[i + 1] := WideChar(PWord(@Buf[i * 3])^ // + Buf[i * 3 + 2] * 256); Result[i + 1] := WideChar(Buf[i * 3] + Buf[i * 3 + 1] * 256 + Buf[i * 3 + 2] * 256); End Result := ''; Finally CloseFile(F); End; End; |
Re: Routine dauert ewig
Zitat:
Delphi-Quellcode:
SetLength(Result, 48);
... Result[I+1] := WideChar(dez); |
Re: Routine dauert ewig
Erst einmal vielen Dank für die rege Beteiligung.
Das Problem ist gelöst :bouncing4: Folgende Infos liefere ich gern nach: Die Zeitmessung war vom Gefühl her. Beim Einlesen ohne Showmessage hat es Minuten gedauert, mit Showmessage (schnelles bestätigen) waren es weniger als 10 Sekunden... Also doch schon aussagekräftig :) Die 20 verschiedenen Dateien selbst waren nur 200-1000 Bytes groß. Ich habe jetzt zwei Änderungen vorgenommen: das Einfügen von
Delphi-Quellcode:
und die Speicheranmeldung bei Result.
wHeader := 0; wHeader2 := 0;
Ich glaube, es lag am undefinierten wHeader2. Vielleicht hatte er wirklich Pseudowerte, die das Auselesen verlängert haben. Warum es aber mit Showmessage ging, kann ich nicht erklären... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:36 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