Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Routine dauert ewig (https://www.delphipraxis.net/89098-routine-dauert-ewig.html)

amigage 26. Mär 2007 11:03


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:
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;
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?

Danke für jeden Hinweis
Amigage

SirThornberry 26. Mär 2007 11:26

Re: Routine dauert ewig
 
daran:
Delphi-Quellcode:
Result := Result + WideChar(dez);
Das ist das schlimmste was du dem Speicher antun kannst.
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

kaiser1401 26. Mär 2007 11:31

Re: Routine dauert ewig
 
aber das erklärt noch nicht das Phänomen das es mit showmessage schneller läuft als ohne, oder?

SirThornberry 26. Mär 2007 11:35

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?

himitsu 26. Mär 2007 11:39

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:
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;
(ich hoff ich hab's richtig übersezt)

Robert Marquardt 26. Mär 2007 11:51

Re: Routine dauert ewig
 
Zitat:

Zitat von SirThornberry
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

Delphi-Quellcode:
SetLength(Result, 48);
...
Result[I+1] := WideChar(dez);

amigage 26. Mär 2007 12:21

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:
wHeader := 0; wHeader2 := 0;
und die Speicheranmeldung bei Result.

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