Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Prozedur beschleunigen / Threads? (https://www.delphipraxis.net/139963-prozedur-beschleunigen-threads.html)

himitsu 9. Sep 2009 11:22

Re: Prozedur beschleunigen / Threads?
 
Delphi-Quellcode:
var StreamH, Stream1, Stream2: TMemoryStream;
  i: Integer;

StreamH.LoadFromFile('Datei3');
Schleife
  Stream1.LoadFromFile('Datei1');
  Stream2.LoadFromFile('Datei2');
  Hash1 := GetMD5(Stream1);
  Hash2 := GetMD5(Stream2);
  Stream1.SaveToFile('Backup');
  Stream2.SaveToFile('Datei1');
  //for i := 0 to StreamH.Size - SizeOf(Hash) do
  //  if CompareMem(@Hash1, PAnsiChar(StreamH.Memory) + i, SizeOf(Hash)) then
  //    MoveMemory(@Hash2, PAnsiChar(StreamH.Memory) + i, SizeOf(Hash));
  i := 0;
  while i <= StreamH.Size - SizeOf(Hash) do
    if CompareMem(@Hash1, PAnsiChar(StreamH.Memory) + i, SizeOf(Hash)) then begin
      MoveMemory(@Hash2, PAnsiChar(StreamH.Memory) + i, SizeOf(Hash));
      Inc(i, SizeOf(Hash));
    end else Inc(i);
Wiederhole
StreamH.SaveToStream('Datei3');
so wären die Lese-/Schreiboperationen auf den Datenträger minimiert

[add]
Bit für Bit hatte ich eher als Byte für Byte verstanden

Delphi-Laie 9. Sep 2009 11:51

Re: Prozedur beschleunigen / Threads?
 
Zitat:

Zitat von Balu der Bär
Beim Ersetzen der MD5-Hashes in datei3 wird bitweise vorgegangen, daher dauert dies etwas.

Mein eigentliches Problem ist: Die gesamte Prozedur dauert selbst auf guten Rechnern um die 2 Minuten, eindeutig zu lang.

Und ersteres dürfte ein, wenn nicht der entscheidende Grund für letzteres sein.

Aus den guten alten Turbo-Pascal-Zeiten nahm ich die Erfahrung mit, daß sich durch Austausch von bitweisen Lese-/Schreiboperationen durch die Funktionen blockread und blockwrite (Blöcke natürlich möglichst, aber nicht über Gebühr groß wählen) der Dateizugriff wesentlich beschleunigen läßt. Delphi als TP-Erbe bietet solche Befehle weiterhin an.

himitsu 9. Sep 2009 12:10

Re: Prozedur beschleunigen / Threads?
 
Das Problem ist ja nicht unbedingt der byteweise Fortschritt, sondern mehr, daß je Byte ab diesem SizeOf(MD5)-Bytes ERNEUT eingelesen werden ... also Dateigröße*SizeOf(MD5) Bytes eingelesen und verglichen werden, wobei man hätte auch mehrere Gruppen, bzw. hier sogar Alles hätte EINMAL einlesen können und dann darin den Vergleich vornehmen.


z.B. pattern um 1000 Byte vergrößern und dann die nächsten bis zu 1000 Vergleiche direkt darin.

jfheins 9. Sep 2009 13:27

Re: Prozedur beschleunigen / Threads?
 
Ich habe so eine Funktion schonmal gesehen :stupid:

Bevor ich als indirekter Autor dieser Codebremse bezichtigt werde, möchte ich mal diese Funktion in den Raum werfen:
Delphi-Quellcode:
procedure ReplaceFile(FileName: String; old, new: Array of MD5Digest)
var
  fs: TFileStream;
  mem: TmemoryStream;
  i: Integer;
begin

  mem := TMemoryStream.Create();

  fs := TFileStream.Create(FileName, fmOpenReadWrite or fmShareExclusive);
  try
    mem.CopyFrom(fs, 0);
   
    for i = low(old) to high(old) do
    begin
      Replace(mem, old[i], new[i]);
    end;
   
    fs.CopyFrom(mem, 0);
   
  finally
    fs.Free;
    mem.Free;
  end;
end;
Bin nicht sicher ob die compiliert, aber
1. Wir statt der Datei ein Memorystream genommen, was den Vorgang beschleunigen dürfte
2. Wird die Datei nur einmal geöffnet, gelesen und nach den ganzen Ersetzungen gespeichert.

Aber vor einem Jahr hieß es doch noch "Brauche ich nicht: Performance egal, Hauptsache es läuft :) " :gruebel:

gammatester 9. Sep 2009 14:31

Re: Prozedur beschleunigen / Threads?
 
Seid ihr sicher, daß Disk-IO die Bremse ist? Ich habe eher das Suchen im Verdacht. Auf jeden Fall ist das "Suchen und Ersetzen" sehr sehr suboptimal :wink: gelöst: Geh an die erste Position und teste, wenn's nix war dann gehe halt an die nächste. Es gibt doch wesentlich besserere Such-Algorithmen (Stichwort zB Boyer-Moore u.ä.), wahrscheinlich schon in der RTL.

Gammatester

himitsu 9. Sep 2009 14:57

Re: Prozedur beschleunigen / Threads?
 
Du duchst Er sucht ja mit massig Disk-I/O :zwinker:

Ständiges hin-und-herspringen in der Datei und auch noch immer wieder winzige Stückchen lesen.

jfheins 9. Sep 2009 15:12

Re: Prozedur beschleunigen / Threads?
 
Wenn man das im Speicher auf nem Memorystream macht, sollte es ja halb so wild sein :stupid:

Da schreibt man die Prozedur extra vielseitig fpr TStream und dann kommen solche Klagen ... :?

gammatester 9. Sep 2009 15:14

Re: Prozedur beschleunigen / Threads?
 
Zitat:

Zitat von himitsu
Du duchst ja mit massig Disk-I/O :zwinker:

Ständiges hin-und-herspringen in der Datei und auch noch immer wieder winzige Stückchen lesen.

duchst??

Meinst Du mich mit dem Beitrag? Wer sagt denn, daß man ständig hin-und-herspringen muß in der Datei. Vor gefühlten 100 Jahren gab's da schon mal von Turbopower eine sauschnelle OpClone-Unit, die das mit Boyer-Moore gemacht hat, damals mit (default) 4KB-Puffer. Könnte man heute wahrscheinlich locker mit 4MB machen.

Gammatester

himitsu 9. Sep 2009 15:36

Re: Prozedur beschleunigen / Threads?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von gammatester
duchst??

Eine Taste nach links. :zwinker:
Und stimmt, es müßte "er sucht" heißen. :oops:

Nja, im Prinzip gibt es da was in meinem himXML (so als offene Quelle),
da wird auch Stückchenweise gelesen und ein Überhang mitgenommen, wenn der Suchtext über den Puffer hinausgeht.



Oder die einfache Version in diesem uralten Projekt.
halt nee, da isses doch nicht drin, aber zumindestens wird da nicht ständig zurückgesprungen

[add]
also quasi

Delphi-Quellcode:
// suchen
Schleife:
  lese Puffer (z.B. 64 KB) // direkt hinter den alten Pufferstring
                            // (der unten kopierte Teil)
  suche in Puffer
  kopiere letze Length(Suchmuster)-1 Bytes nach vorne
wiederhole

// suchen + ersetzen
Schleife:
  lese Puffer (z.B. 64 KB) // direkt hinter den alten Pufferstring
                            // (der unten kopierte Teil)
  Schleife2:
    suche in Puffer
    wenn gefunden, dann ersetzte
  wiederhole
  wenn etwas ersetzt wurde, dann speicher den Puffer
  kopiere letze Length(Suchmuster)-1 Bytes nach vorne
wiederhole


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:24 Uhr.
Seite 2 von 2     12   

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz